原始XML(myfile.xml)
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<blabla
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:blabla="http://www.w3.org/2000/blabla"
xmlns="http://www.w3.org/2000/blabla"
version="1.0">
<title>Hello there</title>
<metadata>
<rdf:RDF>
<cc:whtaat />
</rdf:RDF>
</metadata>
<sometag>
<anothertag id="anothertag1111">
<andanother id="yep" />
</anothertag >
</sometag>
</blabla>
目的是在文档根节点下直接添加一个孩子并在新孩子下“推送”原始孩子:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<blabla
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:blabla="http://www.w3.org/2000/blabla"
xmlns="http://www.w3.org/2000/blabla"
version="1.0">
<magic>
<title>Hello there</title>
<metadata>
<rdf:RDF>
<cc:whtaat />
</rdf:RDF>
</metadata>
<sometag>
<anothertag id="anothertag1111">
<andanother id="yep" />
</anothertag >
</sometag>
</magic>
</blabla>
这个php脚本可以做到
<?php
header("Content-type: text/xml");
// Create dom document
$doc = new DOMDocument();
$doc->load("myfile.xml");
$doc->preserveWhiteSpace = false;
$doc->formatOutput = true;
// Get first child (blabla)
$blablaNode = $doc->firstChild;
// Crete magic element to hold all children in blabla
$magicElement = $doc->createElement('magic');
while($blablaNode->hasChildNodes()) {
// Remove child from blablaNode and append it into magicElement
$magicElement->appendChild($blablaNode->removeChild($blablaNode->firstChild));
}
// Append magicElement to blablaNode
$magicElement = $blablaNode->appendChild($magicElement);
echo $doc->saveXML();
?>
然而输出是
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<blabla xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:blabla="http://www.w3.org/2000/blabla"
xmlns="http://www.w3.org/2000/blabla" version="1.0">
<magic>
<blabla:title xmlns:default="http://www.w3.org/2000/blabla">Hello there</blabla:title>
<blabla:metadata xmlns:default="http://www.w3.org/2000/blabla" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cc="http://creativecommons.org/ns#">
<rdf:RDF>
<cc:whtaat/>
</rdf:RDF>
</blabla:metadata>
<blabla:sometag xmlns:default="http://www.w3.org/2000/blabla">
<blabla:anothertag id="anothertag1111">
<blabla:andanother id="yep"/>
</blabla:anothertag>
</blabla:sometag>
</magic>
</blabla>
所以每个节点(在“默认”命名空间中)都附加了“blaba”前缀
<blabla:title />
如何避免? 在检查ongoings时,如果将PHP更改为
while($blablaNode->hasChildNodes()) {
$removedChild = $blablaNode->removeChild($blablaNode->firstChild);
echo "(prefix for removed:".$removedChild->prefix.")";
$magicElement->appendChild($removedChild);
echo "(prefix for added:".$magicElement->lastChild->prefix.")";
}
echo is ...(已删除的前缀:)(已添加前缀:)(已删除前缀:)(已添加前缀:默认)...
非常感谢提前!
P.S。这是this问题的续集,因此“也许某人有更好的解决方案来实现理想的结果[添加魔法节点并推动其中的所有内容]”仍然适用...
实际上,如果将“默认命名空间声明放在首位”,正如Josh Davis所说,查找前缀消失了。 +1。但就像在输出中一样......
...
<metadata xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#">
...
......声明仍在那里。 澄清。我不是那些XML文档的创建者。因此,检查默认命名空间声明的位置......即使实现它仍然不会给出理想的结果。即使libxml添加的声明应该是标准的,我的任务也不是验证一致性,而是 - 简单地将所有原始子节点保存在其内容(声明,名称值,属性等)中,在该额外新创建的容器下。
答案 0 :(得分:2)
当你追加这些孩子时,我想libxml会查找“http://www.w3.org/2000/blabla”的第一个命名空间声明,并找到“blabla”。现在,如果您首先放置默认命名空间声明,它将发现默认命名空间有效,并且它不会使用blabla为这些节点添加前缀。
<blabla xmlns="http://www.w3.org/2000/blabla"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:blabla="http://www.w3.org/2000/blabla"
version="1.0">
问题完全是装饰性的,但是如果要删除多余的命名空间声明,可以转储并重新加载XML:
$xml = $doc->saveXML();
$doc = new DOMDocument;
$doc->loadXML($xml, LIBXML_NSCLEAN);
echo $doc->saveXML();
如果您重复使用$doc
变量,请注意,这并不意味着像$blablaNode
这样的东西会保持功能,但不会。新的$doc
是一个新文档。
哦,它还会清除原始文档中的冗余命名空间,可能会破坏“保持完整”规则。
哦,我忘了提到你必须明确声明要创建哪个命名空间<magic/>
:
$magicElement = $doc->createElementNS('http://www.w3.org/2000/blabla', 'magic');