fek*_*lee 5 php xml xml-namespaces domdocument
我尝试了什么,什么不起作用:
输入:
$d = new DOMDocument();
$d->formatOutput = true;
// Out of my control:
$someEl = $d->createElementNS('http://example.com/a', 'a:some');
// Under my control:
$envelopeEl = $d->createElementNS('http://example.com/default',
'envelope');
$d->appendChild($envelopeEl);
$envelopeEl->appendChild($someEl);
echo $d->saveXML();
$someEl->prefix = null;
echo $d->saveXML();
Run Code Online (Sandbox Code Playgroud)替换后输出无效XML:
<?xml version="1.0"?>
<envelope xmlns="http://example.com/default">
<a:some xmlns:a="http://example.com/a"/>
</envelope>
<?xml version="1.0"?>
<envelope xmlns="http://example.com/default">
<:some xmlns:a="http://example.com/a" xmlns:="http://example.com/a"/>
</envelope>
Run Code Online (Sandbox Code Playgroud)请注意,<a:some>可能有孩子.一个解决方案是创建一个新的<some>,和所有的孩子从复制<a:some>到<some>.这是要走的路吗?
这确实是一个有趣的问题。我的第一个意图是克隆<a:some>节点,删除xmlns:a属性,删除<a:some>并插入克隆 - <a>。但这是行不通的,因为 PHP 不允许像任何常规属性一样删除 xmlns:a 属性。
在与 PHP 的 DOM 方法进行了一些斗争之后,我开始用 google 搜索这个问题。我在 PHP 文档中找到了这个评论。用户建议编写一个函数来手动克隆节点,而不需要其名称空间:
<?php
/**
* This function is based on a comment to the PHP documentation.
* See: http://www.php.net/manual/de/domnode.clonenode.php#90559
*/
function cloneNode($node, $doc){
$unprefixedName = preg_replace('/.*:/', '', $node->nodeName);
$nd = $doc->createElement($unprefixedName);
foreach ($node->attributes as $value)
$nd->setAttribute($value->nodeName, $value->value);
if (!$node->childNodes)
return $nd;
foreach($node->childNodes as $child) {
if($child->nodeName == "#text")
$nd->appendChild($doc->createTextNode($child->nodeValue));
else
$nd->appendChild(cloneNode($child, $doc));
}
return $nd;
}
Run Code Online (Sandbox Code Playgroud)
使用它会产生如下代码:
$xml = '<?xml version="1.0"?>
<envelope xmlns="http://example.com/default">
<a:some xmlns:a="http://example.com/a"/>
</envelope>';
$doc = new DOMDocument();
$doc->loadXML($xml);
$elements = $doc->getElementsByTagNameNS('http://example.com/a', 'some');
$original = $elements->item(0);
$clone = cloneNode($original, $doc);
$doc->documentElement->replaceChild($clone, $original);
$doc->formatOutput = TRUE;
echo $doc->saveXML();
Run Code Online (Sandbox Code Playgroud)