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();
?>

引用符なしで「DomDocumentreplacechild」をグーグルで検索したときに問題が見つかりました

ここの最初のコメントを参照してください: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 に答える