我有下一种类型的XML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test SYSTEM "dtd">
<root>
<tag1>
<1>Name</1>
<2>Num1</2>
<3>NumOrder</3>
<4>test</5>
<6>line</6>
<7>HTTP </7>
<8>1</8>
<9></9>
</tag1>
<tag2>
<1>Name</1>
<2>Num1</2>
<3>NumOrder</3>
<4>test</5>
<6>line</6>
<7>HTTP </7>
<8>1</8>
<9></9>
</tag2>
...
<tagN>
<1>Name</1>
<2>Num1</2>
<3>NumOrder</3>
<4>test</5>
<6>line</6>
<7>HTTP </7>
<8>1</8>
<9></9>
</tagN>
</root>
我需要在保存为HTML的数组中分别获取每个子元素的根目录:
array = [rootwithchild1,rootwithchild2 ... N];
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test SYSTEM "dtd">
<root>
<tagN>
<1>Name</1>
<2>Num1</2>
<3>NumOrder</3>
<4>test</5>
<6>line</6>
<7>HTTP </7>
<8>1</8>
<9></9>
</tagN>
</root>
现在我制作了2个doms,其中一个让所有孩子分开,另一个我已经删除了所有孩子而只留下了根。在这些步骤中,我想将每个子项添加到root,保存为html,删除子项等等,但这并不起作用。
$bodyNode = $copydoc->getElementsByTagName('root')->item(0);
foreach ($mini as $value) {
$bodyNode->appendChild($value);
$result[] = $copydoc->saveHTML();
$bodyNode->removeChild($value);
}
$ bodyNode-&gt; appendChild($ value)上的错误; Mini 是切割孩子的阵列。 Lib: $ doc = new DOMDocument();
任何人都可以建议如何做到这一点,也许更好地使用xpath或其他东西..? 感谢
答案 0 :(得分:1)
我只想创建一个只包含root
元素和“假”初始子元素的新文档:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test SYSTEM "dtd">
<root>
<fakechild />
</root>
之后,循环遍历原始文档的子元素 - 并为每个元素执行以下步骤:
使用DOMDocument::importNode
使用DOMNode::replaceChild
将根元素的firstChild
作为第二个参数替换导入节点的新文档根元素的当前子节点
保存新文件
(在根元素中开始使用<fakechild />
在技术上是不必要的,一个简单的空白文本节点也应该这样做 - 但是使用空根元素这将不起作用以这种直接的方式,因为firstChild
会在第一次循环迭代中给你NULL,所以你不会有一个节点作为第二个参数提供给DOMNode::replaceChild
。当然你可以做额外的检查并且使用appendChild
而不是replaceChild
作为第一项...但为什么复杂的东西超过必要的。)
答案 1 :(得分:0)
DOMNode :: getElemementsByTagName()返回实时结果。因此,如果从DOM中删除节点,它也会从节点列表中删除。
您可以向后迭代列表......
for ($i = $nodes->length - 1; $i >= 0; $i--) {
$node = $nodes->item($i);
...
}
...或将其复制到数组:
foreach (iterator_to_array($nodes) as $node) {
...
}
来自DOMXpath :: evaluate()的节点列表不会受到影响。 XPath也允许更具体的节点选择。
$xpath = new DOMXpath($domDocument);
$nodes = $xpath->evaluate('/root/*');
foreach (iterator_to_array($nodes) as $node) {
...
}
但我想知道你为什么修改(破坏)原始的XML源?
如果要创建一个新文档作为模板和。永远不要删除节点,只创建新文档并导入它们:
// load the original source
$source= new DOMDocument();
$source->loadXml($xml);
$xpath = new DOMXpath($source);
// create a template dom
$template = new DOMDocument();
$parent = $template;
// add a node and all its ancestors to the template
foreach ($xpath->evaluate('/root/part[1]/ancestor-or-self::*') as $node) {
$parent = $parent->appendChild($template->importNode($node, FALSE));
}
// for each of the child element nodes
foreach ($xpath->evaluate('/root/part/*') as $node) {
// create a new target
$target = new DOMDocument();
// import the nodes from the template
$target->appendChild($target->importNode($template->documentElement, TRUE));
// find the first element node that has no child element nodes
$targetXpath = new DOMXpath($target);
$targetNode = $targetXpath->evaluate('//*[count(*) = 0]')->item(0);
// append the child node from the original xml
$targetNode->appendChild($target->importNode($node, TRUE));
echo $target->saveXml(), "\n\n";
}