Я не думаю, что вы можете изменить, это. Вам придется заменить элементы. Для этого вам нужно будет все узлы элементов (или узлы, которые вы хотите изменить):
$xpath->evaluate('//*')
EVALUATE возвращают узлы в порядке документа. Это означает, что мы получаем родительские узлы перед их детьми. Преобразуйте список в массив и отмените его.
$nodes = array_reverse(iterator_to_array($xpath->evaluate('//*')));
Теперь для каждого элемента создать замену в целевом пространстве имен
$replacement = $dom->createElementNS('urn:foo', 'foo:'.$node->localName);
Получить все дочерние и узлы атрибутов и добавить их к замене:
foreach ($xpath->evaluate('node()|@*', $node) as $childNode) {
$replacement->appendChild($childNode);
}
Последняя , замените исходный узел на новый:
$node->parentNode->replaceChild($replacement, $node);
Полный пример:
$xml = <<<'XML'
<user id="abc">
<name>username</name>
<!-- comment -->
</user>
XML;
$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXpath($dom);
$nodes = array_reverse(
iterator_to_array(
$xpath->evaluate('//*')
)
);
foreach ($nodes as $node) {
$replacement = $dom->createElementNS('urn:foo', 'foo:'.$node->localName);
foreach ($xpath->evaluate('node()|@*', $node) as $childNode) {
$replacement->appendChild($childNode);
}
$node->parentNode->replaceChild($replacement, $node);
}
echo $dom->saveXml();
Выход:
<?xml version="1.0"?>
<foo:user xmlns:foo="urn:foo" id="abc">
<foo:name>username</foo:name>
<!-- comment -->
</foo:user>