您可以使用DOMNode::insertBefore() http://www.php.net/manual/en/domnode.insertbefore.php:
<?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>
希望这可以帮助 :)
EDIT
参考您报告的问题...我看到问题:input#username
不是 的直系子代div#container
,它是form
。所以你需要得到form
元素作为DOMNode
对象,而不是其父对象div#container
。最简单的方法就是添加一个 idform
并做这样的事情:
$form = $doc->getElementById('form');
$username = $doc->getElementById('username');
$username->setAttribute('value', 'Enter username!');
var_dump($doc->saveHTML());
这是基于以下 HTML。请注意form
元素有一个 id:
<div id="container">
<form id="form" method="post" action="">
<input type="text" name="username" id="username">
</form>
</div>
如果由于某种原因你无法向表单元素添加 id,你可以从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.
EDIT #2
我差点忘了 XPath...如果你想变得更简洁/更具冒险精神,你可以使用DOMXPath::query() https://www.php.net/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 查询语法相当神秘但功能强大,无论如何我都不能说我是专家,所以我不能谈论这些查询的效率。另外你可能想添加错误检查 -query
方法返回一个DOMNodeList
其中有一个length
财产。
最后值得注意的是DOMDocument
用一个装饰你的 HTML 片段DOCTYPE
and html
and body
标签;这就是为什么 XPath 查询从body
.