Почему getElementsByTagName захватывает только все остальные элементы здесь? - PullRequest
1 голос
/ 12 августа 2011

С этим кодом, используя DomDocument:

<code><?php
$html = '<pre>one
two
three
four
'; $ doc = new DomDocument (); $ Doc-> loadHTML ($ HTML); $ sub = $ doc-> getElementsByTagName ("pre"); foreach ($ sub как $ pre) { $ фрагмент = $ doc-> createDocumentFragment (); $ frag-> appendXML (str_replace ('&', '& amp;', '

и заменено

')); $ pre-> parentNode-> replaceChild ($ фрагмент, $ pre); } echo $ doc-> saveHTML (); ?>

Я получаю этот вывод:

<code><p>& it's replaced</p> 
<pre>two

и заменено

four

Рабочий (или нет) пример

Может кто-нибудь объяснить мне, что происходит и почему все теги pre не заменяются?

Ответы [ 2 ]

4 голосов
/ 12 августа 2011

Вы можете попробовать это следующим образом: http://codepad.viper -7.com / ALYWEi

<code><?php
$html = '<pre>one
two
three
four
';$ doc = new DomDocument ();$ Doc-> loadHTML ($ HTML);$ sub = $ doc-> getElementsByTagName ("pre");$ i = $ sub-> length - 1;while ($ i> -1) {$ pre = $ sub-> item ($ i);$ фрагмент = $ doc-> createDocumentFragment ();$ frag-> appendXML (str_replace ('&', '&', '

& заменено

'));$ pre-> parentNode-> replaceChild ($ фрагмент, $ pre);$ I--;} echo $ doc-> saveHTML ();?>

Я обнаружил проблему, когда погуглил «DomDocument replacechild» без кавычек

см. Первый комментарий здесь: http://php.net/manual/en/domnode.replacechild.php особенно это:

Если вы пытаетесь заменить более одного узла одновременно, вы должны быть осторожны при переборе DOMNodeList.Если имя старого узла отличается от имени нового узла, оно будет удалено из списка после его замены.Используйте регрессивную петлю:

1 голос
/ 12 августа 2011

Это как-то связано с направлением:

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 Andreas

...