原始 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 />
如何避免这种情况?
如果将 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 是 ...(删除的前缀:)(添加的前缀:)(删除的前缀:)(添加的前缀: 默认)...
提前谢谢了!
附言这是 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 添加的那些声明应该在那里,我的任务也不是验证一致性,而是
- 简单地放置所有原始子节点,完整的内容(声明、名称值、属性等) , 在那个额外的新创建的容器下。
最佳答案
当您附加这些子项时,我猜 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
是一个新文件。哦,它还会从原始文档中清除多余的 namespace ,可能会破坏“保持完整”规则。
哦,我忘了提到你必须明确声明哪个命名空间
<magic/>
将被创建为:$magicElement = $doc->createElementNS('http://www.w3.org/2000/blabla', 'magic');
关于php - 使节点在更改 XML 结构后忽略命名空间(前缀)。 PHP DOM文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3073631/