1

通过使用 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('&', '&amp;', '<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标签都没有被替换吗?

4

2 回答 2

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('&', '&amp;', '<p>& it\'s replaced</p>'));


    $pre->parentNode->replaceChild($fragment, $pre);

    $i--;
} 

echo $doc->saveHTML();
?>

我在没有引号的情况下搜索“DomDocument replacechild”时发现了问题

在这里看到第一条评论:http: //php.net/manual/en/domnode.replacechild.php特别是这个:

如果您尝试一次替换多个节点,则必须小心遍历 DOMNodeList。如果旧节点与新节点的名称不同,则一旦被替换,它将从列表中删除。使用回归循环:

于 2011-08-12T03:30:54.033 回答
1

它与方向有关:

for ($i = 0; $i < $sub->length; $i++) {
    $pre = $sub->item($i);
    $fragment = $doc->createDocumentFragment();
    $fragment->appendXML(str_replace('&', '&amp;', '<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('&', '&amp;', '<p>& it\'s replaced</p>'));
    $pre->parentNode->replaceChild($fragment, $pre);
}

工作正常。我想肯定有一个内部计数器之类的东西。

HTH安德烈亚斯

于 2011-08-12T03:51:01.433 回答