You've probably oversimplified the code, as it stands it will only replace the opening tag, which will at least cause the browser to hop into quirks mode.
Anyways, this is definitely possible using DOM (though it will throw warnings because of unsupported HTML5 elements, see https://stackoverflow.com/a/6090728/1392379), however your XPath query is wrong, you cannot simply pass an array into it. And even if your query would work, it would only select all the individual text nodes, so there wouldn't be anything to replace.
Changing the name of a node is not possible directly, you'll have to replace the node with a new one. Here's an example that uses a static XPath query. It copies the selected nodes attributes and child nodes into a new div
node, and then replaces the original node with the new one:
$dom = new DOMDocument;
$dom->loadHTML($content);
$xp = new DOMXPath($dom);
$nodes = $xp->query('//*[self::article|self::summary|self::aside][not(ancestor::pre) and not(ancestor::code)]');
foreach($nodes as $node)
{
$newNode = $dom->createElement('div');
while($node->childNodes->length)
{
$childNode = $node->childNodes->item(0);
$newNode->appendChild($dom->importNode($childNode, true));
}
while($node->attributes->length)
{
$attributeNode = $node->attributes->item(0);
$newNode->setAttributeNode($dom->importNode($attributeNode));
}
$node->parentNode->replaceChild($newNode, $node);
}
echo $dom->saveXML($dom->documentElement);
Update Fixed the code example by using while
instead of a foreach
on childNodes/attributes
. The latter will cause a hickup when not cloning the node that is going to be appended and consequently removed from the node list being iterated.
Using a for
loop should work fine too:
for($i = 0; $i < $node->childNodes->length; $i ++)
{
$childNode = $node->childNodes->item($i);
$newNode->appendChild($dom->importNode($childNode, true));
}
for($i = 0; $i < $node->attributes->length; $i ++)
{
$attributeNode = $node->attributes->item($i);
$newNode->setAttributeNode($dom->importNode($attributeNode));
}
as well as the cloning mentioned initially:
foreach($node->childNodes as $childNode)
{
$newNode->appendChild($dom->importNode($childNode->cloneNode(true), true));
}
foreach($node->attributes as $attributeNode)
{
$newNode->setAttributeNode($dom->importNode($attributeNode->cloneNode()));
}
$node->parentNode->replaceChild($newNode, $node);