使用此代码使用DomDocument:
<?php
$html = '<pre>one</pre><pre>two</pre><pre>three</pre><pre>four</pre>';
$doc = new DomDocument();
$doc->loadHTML($html);
$sub = $doc->getElementsByTagName("pre");
foreach($sub as $pre) {
$fragment = $doc->createDocumentFragment();
$fragment->appendXML(str_replace('&', '&', '<p>& it\'s replaced</p>'));
$pre->parentNode->replaceChild($fragment, $pre);
}
echo $doc->saveHTML();
?>
我得到了这个输出:
<p>& it's replaced</p>
<pre>two</pre>
<p>& it's replaced</p>
<pre>four</pre>
有人可以向我解释发生了什么以及为什么所有pre
标签都没有被替换?
答案 0 :(得分:4)
您可以尝试这种方式:http://codepad.viper-7.com/ALYWEi
<?php
$html = '<pre>one</pre><pre>two</pre><pre>three</pre><pre>four</pre>';
$doc = new DomDocument();
$doc->loadHTML($html);
$sub = $doc->getElementsByTagName("pre");
$i = $sub->length - 1;
while ($i > -1) {
$pre = $sub->item($i);
$fragment = $doc->createDocumentFragment();
$fragment->appendXML(str_replace('&', '&', '<p>& it\'s replaced</p>'));
$pre->parentNode->replaceChild($fragment, $pre);
$i--;
}
echo $doc->saveHTML();
?>
当我用Google搜索“DomDocument replacechild”而没有引号
时,我发现了这个问题请在此处查看第一条评论:http://php.net/manual/en/domnode.replacechild.php,尤其是:
如果您尝试一次替换多个节点,则必须小心迭代DOMNodeList。如果旧节点具有与新节点不同的名称,则一旦替换它,它将从列表中删除。使用回归循环:
答案 1 :(得分:1)
这与方向有关:
for ($i = 0; $i < $sub->length; $i++) {
$pre = $sub->item($i);
$fragment = $doc->createDocumentFragment();
$fragment->appendXML(str_replace('&', '&', '<p>& it\'s replaced</p>'));
$pre->parentNode->replaceChild($fragment, $pre);
}
不起作用,但
for ($i = $sub->length -1; $i >=0; $i--) {
$pre = $sub->item($i);
$fragment = $doc->createDocumentFragment();
$fragment->appendXML(str_replace('&', '&', '<p>& it\'s replaced</p>'));
$pre->parentNode->replaceChild($fragment, $pre);
}
工作正常。我估计必须有类似内部计数器的东西。
HTH Andreas