Replace tag in HTML with DOMDocument

I am trying to edit html tags using DOMDocument :: loadHTML in php. The html data is part of html, not the whole page. I followed this page ( PHP - DOMDocument - should replace / replace an existing HTML tag with a new one ).

This should convert the pre-tags to div tags, but it gives a "Fatal error: Uncaught exception" DOMException with the message "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] Although I am trying to iterate the node object backwards, I get this error: "Note: trying to get a non-object property ..."

 <?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, decided. Since the response code has some error, I post the solution here. Thanks to everyone.

Decision:

 <?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(); ?> 
+3
source share
2 answers

The problem is calling replaceChild() . Instead

 $dom->replaceChild($nodeDiv, $nodePre); 

using

 $nodePre->parentNode->replaceChild($nodeDiv, $nodePre); 

Update

Here is the working code. There seems to be a problem with replacing multiple nodes (more details here: http://php.net/manual/en/domnode.replacechild.php ), so you will have to use a regression loop to replace the elements.

 $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); } 
+8
source

Another way with paquettg / php-html-parser (did not find a way to change the name, so I had to use hack with 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; 
+1
source

All Articles