In PHP with DOM, I have a DomElement object which represents an
I have one case where I need to change this so its element name is
NOTE: I tried Calvin's code and it sort of worked for me but not quite. If the tag I was replacing had nested tags, some child tags would sometimes get lost.
The reason is that childNodes is a live DOMNodeList of a node's children, and appendChild moves the nodes around in the DOM, thus affecting the list ordering. If you just do foreach on a childNodes the loop can skip some children.
My solution was to use a while loop. This way you don't have to copy any nodes to an array.
I have packaged everything in a convenient function that takes a string and returns a string and should work with utf-8. The following is tested in PHP 5.5.9.
function renameTags($html, $oldname, $name) {
$dom = new DOMDocument( '1.0', 'utf-8' );
$fragment = $dom->createDocumentFragment();
if ( $fragment->appendXML( $html ) ) {
$dom->appendChild( $fragment );
$nodesToAlter = $dom->getElementsByTagName( $oldname );
while ($nodesToAlter->length) {
$node = $nodesToAlter->item(0);
$newnode = $node->ownerDocument->createElement($name);
while ($node->hasChildNodes()) {
$child = $node->childNodes->item(0);
$child = $node->ownerDocument->importNode($child, true);
$newnode->appendChild($child);
}
foreach ($node->attributes as $attr) {
$attrName = $attr->nodeName;
$attrValue = $attr->nodeValue;
$newnode->setAttribute($attrName, $attrValue);
}
$newnode->ownerDocument->replaceChild($newnode, $node);
}
return $dom->saveHTML();
} else {
//error
}
}
$html = 'Testing nested tags in html strings and stuff';
echo renameTags($html, 'b', 'strong');
Prints:
Testing nested tags in html strings and stuff