...">

How to use XPath and DOM to replace node / element in php?

Say I have the following html

$html = ' <div class="website"> <div> <div id="old_div"> <p>some text</p> <p>some text</p> <p>some text</p> <p>some text</p> <div class="a class"> <p>some text</p> <p>some text</p> </div> </div> <div id="another_div"></div> </div> </div> '; 

And I want to replace #old_div with the following:

 $replacement = '<div id="new_div">this is new</div>'; 

To give the final result:

 $html = ' <div class="website"> <div> <div id="new_div">this is new</div> <div id="another_div"></div> </div> </div> '; 

Is there a simple cut and paste function for this with PHP?


The final working code thanks to all the help of Gordon:

 <?php $html = <<< HTML <div class="website"> <div> <div id="old_div"> <p>some text</p> <p>some text</p> <p>some text</p> <p>some text</p> <div class="a class"> <p>some text</p> <p>some text</p> </div> </div> <div id="another_div"></div> </div> </div> HTML; $dom = new DOMDocument; $dom->loadXml($html); // use loadHTML if it invalid XHTML //create replacement $replacement = $dom->createDocumentFragment(); $replacement ->appendXML('<div id="new_div">this is new</div>'); //make replacement $xp = new DOMXPath($dom); $oldNode = $xp->query('//div[@id="old_div"]')->item(0); $oldNode->parentNode->replaceChild($replacement , $oldNode); //save html output $new_html = $dom->saveXml($dom->documentElement); echo $new_html; ?> 
+7
source share
2 answers

Since the answer in the linked duplicate is not exhaustive, I will give an example:

 $dom = new DOMDocument; $dom->loadXml($html); // use loadHTML if its invalid (X)HTML // create the new element $newNode = $dom->createElement('div', 'this is new'); $newNode->setAttribute('id', 'new_div'); // fetch and replace the old element $oldNode = $dom->getElementById('old_div'); $oldNode->parentNode->replaceChild($newNode, $oldNode); // print xml echo $dom->saveXml($dom->documentElement); 

Technically, you don't need XPath for this. However, it may happen that your version of libxml cannot execute getElementById for unaudited documents ( id attributes are special in XML ). In this case, replace the call with getElementById with

 $xp = new DOMXPath($dom); $oldNode = $xp->query('//div[@id="old_div"]')->item(0); 

Code Demo


To create $newNode with child nodes without having to create and add elements one by one, you can do

 $newNode = $dom->createDocumentFragment(); $newNode->appendXML(' <div id="new_div"> <p>some other text</p> <p>some other text</p> <p>some other text</p> <p>some other text</p> </div> '); 
+11
source

use jquery hide () first to hide a specific div, and then use append to add a new div

 $('#div-id').remove(); $('$div-id').append(' <div id="new_div">this is new</div>'); 
-7
source

All Articles