In PHP with DOM, I have a DomElement object which represents an <identity/> element.
I have one case where I need to change this so its element name is <person/>, but keep the same child elements and attributes.
What would be the simplest way of changing an element name of a DomElement and keeping its children and attributes?
Edit: I have just found a very similar question (though it doesn't have very good answers).
Use the setAttribute() method to change the name attribute of an element, e.g. box. setAttribute('name', 'example-name') . The method sets or updates the value of an attribute on the specified element. Here is the HTML for the examples in this article.
Users can use getElementById() method to access HTML element using the id. If any element doesn't exist with the passed id into the getElementById method, it returns the null value. Syntax: document.
Could you use importNode()
to copy the childNodes of your <identity>
element to a newly created <person>
element?
function changeName($node, $name) {
$newnode = $node->ownerDocument->createElement($name);
foreach ($node->childNodes as $child){
$child = $node->ownerDocument->importNode($child, true);
$newnode->appendChild($child, true);
}
foreach ($node->attributes as $attrName => $attrNode) {
$newnode->setAttribute($attrName, $attrNode);
}
$newnode->ownerDocument->replaceChild($newnode, $node);
return $newnode;
}
$domElement = changeName($domElement, 'person');
Perhaps something like that would work, or you could try using cloneChild()
.
Edit: Actually, I just realized that the original function would lose the placement of the node. As per the question thomasrutter linked to, replaceChild()
should be used.
Thanks to your post, I could quickly solve the same issue for me. However, I had a DOM_NOT_FOUND exception. This is probably a PHP Version issue, since the original post is 5 years old.
According to the PHP Documentation (Feb 2014)
DOM_NOT_FOUND
Raised if oldnode is not a child of this node.
So, I have replaced
$newnode->ownerDocument->replaceChild($newnode, $node);
with
$node->parentNode->replaceChild($newnode, $node);
Here is the complete function (tested):
public static function changeTagName($node, $name) {
$childnodes = array();
foreach ($node->childNodes as $child){
$childnodes[] = $child;
}
$newnode = $node->ownerDocument->createElement($name);
foreach ($childnodes as $child){
$child2 = $node->ownerDocument->importNode($child, true);
$newnode->appendChild($child2);
}
foreach ($node->attributes as $attrName => $attrNode) {
$attrName = $attrNode->nodeName;
$attrValue = $attrNode->nodeValue;
$newnode->setAttribute($attrName, $attrValue);
}
$node->parentNode->replaceChild($newnode, $node);
return $newnode;
}
It is also worth mentioning that when you want to use this function, you should traverse the DOM Tree in reversed order as explained in other posts.
UPDATE: After months of using and updating to PHP Version 5.5.15 on windows, I had an error saying $attr could not be converted to a string. So I updated third for-each loop above.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With