我正在尝试使用php中的DOMDocument :: loadHTML编辑html标签。 html数据是html的一部分,而不是整个页面。我按照这个页面(PHP - DOMDocument - need to change/replace an existing HTML tag w/ a new one)说的那样。
这应该将pre标签转换为div标签,但它会给出“致命错误:未捕获异常'DOMException',并显示消息'Not Found Error'。”
<?php
$contents = <<<STR
<pre>hi</pre>
<pre>hello</pre>
<pre>bye</pre>
STR;
$dom = new DOMDocument;
@$dom->loadHTML($contents);
foreach( $dom->getElementsByTagName("pre") as $nodePre ) {
$nodeDiv = $dom->createElement("div", $nodePre->nodeValue);
$dom->replaceChild($nodeDiv, $nodePre);
}
echo $dom->saveHTML();
?>
[编辑] 当我试图向后迭代节点对象时,我得到了这个错误,'注意:试图获取非对象的属性......'
<?php
$contents = <<<STR
<pre>hi</pre>
<pre>hello</pre>
<pre>bye</pre>
STR;
$dom = new DOMDocument;
@$dom->loadHTML($contents);
$domPre = $dom->getElementsByTagName('pre');
$length = $domPre->length;
For ($i = $length; $i > -1 ; $i--) {
$nodePre = $domPre->item($i);
echo $nodePre->nodeValue . '<br />';
// $nodeDiv = $dom->createElement("div", $nodePre->nodeValue);
// $dom->replaceChild($nodeDiv, $nodePre);
}
// echo $dom->saveHTML();
?>
[编辑] 哦,解决了。由于答案代码有一些错误,我在这里发布解决方案。谢谢大家。
解决方案:
<?php
$contents = <<<STR
<pre>hi</pre>
<pre>hello</pre>
<pre>bye</pre>
STR;
$dom = new DOMDocument;
@$dom->loadHTML($contents);
$domPre = $dom->getElementsByTagName('pre');
$length = $domPre->length;
For ($i = $length - 1; $i > -1 ; $i--) {
$nodePre = $domPre->item($i);
$nodeDiv = $dom->createElement("div", $nodePre->nodeValue);
$nodePre->parentNode->replaceChild($nodeDiv, $nodePre);
}
echo $dom->saveHTML();
?>
答案 0 :(得分:12)
问题是对replaceChild()
的调用。而不是
$dom->replaceChild($nodeDiv, $nodePre);
使用
$nodePre->parentNode->replaceChild($nodeDiv, $nodePre);
<强>更新强>
这是一个有效的代码。似乎替换多个节点存在一些问题(此处有更多信息:http://php.net/manual/en/domnode.replacechild.php),因此您必须使用回归循环来替换元素。
$contents = <<<STR
<pre>hi</pre>
<pre>hello</pre>
<pre>bye</pre>
STR;
$dom = new DOMDocument;
@$dom->loadHTML($contents);
$elements = $dom->getElementsByTagName("pre");
for ($i = $elements->length - 1; $i >= 0; $i --) {
$nodePre = $elements->item($i);
$nodeDiv = $dom->createElement("div", $nodePre->nodeValue);
$nodePre->parentNode->replaceChild($nodeDiv, $nodePre);
}
答案 1 :(得分:1)
使用paquettg/php-html-parser的另一种方法(没有找到更改名称的方法,所以不得不使用hack重新绑定$this
):
use PHPHtmlParser\Dom;
use PHPHtmlParser\Dom\HtmlNode;
$dom = new Dom;
$dom->load($text);
/** @var HtmlNode[] $tags */
foreach($dom->find('pre') as $tag) {
$changeTag = function() {
$this->name = 'div';
};
$changeTag->call($tag->tag);
};
echo (string)$dom;