在php dom中将命名空间添加到xml的现有节点

时间:2014-02-10 11:17:30

标签: php xml dom

我有这个:

<user>
     <!-- data here -->
</user>

我想要这个:

<namespace:user>
    <!-- data here -->
</namespace:user>

我尝试设置$prefix DomnNode的user属性。但它没有效果。怎么做?

1 个答案:

答案 0 :(得分:0)

我认为你不能改变它。您将不得不替换元素。为此,您需要所有元素节点(或您想要更改的节点):

$xpath->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>