Как я могу использовать XPath и DOM для замены узла / элемента в 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> '; 

И я хочу заменить #old_div следующим:

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

Чтобы дать конечный результат:

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

Есть ли простая функция вырезания и вставки для этого с PHP?


Заключительный рабочий код благодаря всей помощи Гордона:

 <?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's 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; ?> 

Поскольку ответ в связанном дубликате не является исчерпывающим, я приведу пример:

 $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); 

Технически, для этого вам не нужен XPath. Однако может случиться так, что ваша версия libxml не может сделать getElementById для неаудированных документов ( атрибуты id являются особыми в XML ). В этом случае замените вызов getElementById на

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

Демо на кодовом коде


Чтобы создать $newNode с дочерними узлами без необходимости создавать и добавлять элементы один за другим, вы можете сделать

 $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> '); 

сначала используйте jquery hide (), чтобы скрыть конкретный div, а затем используйте append для добавления нового div

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