<?php
$XML = '
<html>
<h1>Hello</h1>
<ol>
<li>test (no id)</li>
<li xml:id="i2">test i2</li>
</ol>
</html>
';
$doc = new DOMDocument;
$doc->loadXML($XML);
$xpath = new DOMXpath($doc);
// get the ol
$olNode = $xpath->evaluate('//ol[1]', NULL, FALSE)->item(0);
// append a new list item
$olNode->appendChild($liNode = $doc->createElement('li'));
$liNode->appendChild($doc->createTextNode('test i3'));
$liNode->setAttribute('xml:id', 'i3');
// show new DOM state
print $doc->saveXML();
// insert a new list item before the others
$olNode->insertBefore($liNode = $doc->createElement('li'), $olNode->firstChild);
$liNode->appendChild($doc->createTextNode('test i0'));
$liNode->setAttribute('xml:id', 'i0');
// show new DOM state
print $doc->saveXML();
// fetch the li nodes without an xml:id
$nodes = $xpath->evaluate('//ol/li[not(@xml:id)]', NULL, FALSE);
// and remove them in reverse order
for ($i = $nodes->length - 1; $i >= 0; --$i) {
$nodes->item($i)->parentNode->removeChild($nodes->item($i));
}
// show new DOM state
print $doc->saveXML();
// replace the li[@xml:id'i2'] with a new node
$liNode = $doc->getElementById('i2');
$followingNode = $liNode->nextSibling;
$odNode = $liNode->parentNode;
$olNode->removeChild($liNode);
$olNode->insertBefore($liNode = $doc->createElement('li'), $followingNode);
$liNode->appendChild($doc->createTextNode('test i2 replaced'));
$liNode->setAttribute('xml:id', 'i2');
// show new DOM state
print $doc->saveXML();
// NOT REFRESHING!?!
var_dump($doc->getElementById('i2')); // object(DOMElement)#5 (0) { } li
//CAN_NOT_doMORESomeChange($doc);
$doc->loadXML($doc->saveXML()); // only way to refresh?
print $doc->getElementById('i2')->tagName; //OK, is there
// be ware that the xpath still uses the old document
var_dump($xpath->document === $doc);