PHP DomDocument HTML操作
作者:互联网
我有以下HTML.
<div id="container">
<div id="current">Current Div</div>
</div>
我在PHP中使用DomDocument,试图在id为“ current”的div之前向HTML添加一个额外的div.
<div id="container">
<div id="new">New Div</div>
<div id="current">Current Div</div>
</div>
当我使用以下代码时,似乎在div内添加了div,其ID为“ current”,但在该div的内容之前.有人可以告诉我这是为什么,以及如何获得类似于上述HTML的结果? (请参见下面的HTML问题)
当前的PHP
$doc = new DOMDocument();
$doc->formatOutput = true;
$doc->loadHTMLFile('index.html');
$head = $doc->getElementById('current');
$base = $doc->createElement('div', 'New Div');
$base->setAttribute('id', 'new');
echo $doc->saveHTML();
HTML问题
<div id="container">
<div id="current">
<div id="new">New Div</div>
Current Div
</div>
</div>
编辑:
的PHP
$doc = new DOMDocument();
$doc->formatOutput = true;
$doc->loadHTMLFile('index.html');
$container = $doc->getElementById('container');
$current = $doc->getElementById('username');
$new = $doc->createElement('div', 'New Div');
$new->setAttribute('id', 'new');
$container->insertBefore($new, $current);
echo $doc->saveHTML();
的HTML
<div id="container">
<form method="post" action="">
<input type="text" name="username" id="username" />
</form>
</div>
错误:
Fatal error: Uncaught exception 'DOMException' with message 'Not Found Error'
in index.php:55 Stack trace: #0 index.php(55):
DOMNode->insertBefore(Object(DOMElement), Object(DOMElement))
解决方法:
您可以使用DOMNode::insertBefore()
:
<?php
$doc = new DOMDocument();
$doc->formatOutput = true;
$doc->loadHTMLFile('index.html');
$container = $doc->getElementById('container');
$current = $doc->getElementById('current');
$new = $doc->createElement('div', 'New Div');
$new->setAttribute('id', 'new');
$container->insertBefore($new, $current);
var_dump($doc->saveHTML());
这样产生:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<body>
<div id="container">
<div id="new">New Div</div>
<div id="current">Current Div</div>
</div>
</body>
</html>
希望这可以帮助 :)
编辑
关于您报告的问题…我看到了问题:input#username不是div#container的直接子代,它是form的直接子代.因此,您需要将form元素作为DOMNode对象而不是其父div#container来获取.最简单的方法是在表单中添加一个ID,然后执行以下操作:
$form = $doc->getElementById('form');
$username = $doc->getElementById('username');
$username->setAttribute('value', 'Enter username!');
var_dump($doc->saveHTML());
这是基于以下HTML.请注意,表单元素具有一个ID:
<div id="container">
<form id="form" method="post" action="">
<input type="text" name="username" id="username">
</form>
</div>
如果由于某种原因无法将id添加到form元素,则可以像这样从div#container遍历:
// find div#container element
$container = $doc->getElementBy('id');
// find all form elements that are children of div#container
$forms = $container->getElementsByTagName('form');
if (0 !== $forms->length) {
$form = $forms->item(0);
}
// etc.
编辑#2
我差点忘了XPath …如果您想变得更简洁/喜欢冒险,可以使用DOMXPath::query()
查找DOM节点:
$xpath = new DOMXPath($doc);
$form = $xpath->query('body/div[@id="container"]/form')->item(0);
$input = $xpath->query('body//input[@id="username"]')->item(0);
XPath查询语法非常隐秘但功能强大,我不能以任何方式说自己是专家,所以我不能说这些查询的效率.另外,您可能想添加错误检查-查询方法返回具有length属性的DOMNodeList.
最后,值得注意的是DOMDocument用DOCTYPE和html和body标签装饰HTML片段.这就是XPath查询从正文遍历的原因.
标签:domdocument,html,php 来源: https://codeday.me/bug/20191122/2060427.html