Заменить тег в HTML с помощью DOMDocument

Я пытаюсь редактировать html-теги с DOMDocument :: loadHTML в php. Данные html являются частью html, а не всей страницы. Я последовал за тем, что эта страница ( PHP – DOMDocument – нужно изменить / заменить существующий тег HTML с новым ).

Это должно преобразовать pre-теги в теги div, но это дает «Fatal error: Uncaught exception« 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(); ?> 

[Edit] Пока я пытаюсь выполнить итерацию объекта узла назад, я получаю эту ошибку: «Обратите внимание: попытка получить свойство не-объекта …»

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

[Edit] Okey, решено. Так как ответный код имеет некоторую ошибку, я размещаю решение здесь. Спасибо всем.

Решение:

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

Проблема заключается в вызове 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); } 

Другой способ с paquettg / php-html-parser (не нашел способ изменить имя, поэтому пришлось использовать взломать с re-binding $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;