PHPDOM将xml切割成碎片,并将每个子项与父项单独保存
我有下一种类型的XML:PHPDOM将xml切割成碎片,并将每个子项与父项单独保存,php,xml,dom,Php,Xml,Dom,我有下一种类型的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
<?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>
$bodyNode->appendChild($value)上的错误;
Mini是切割子对象的数组。
Lib:$doc=newDOMDocument()
有没有人能建议如何正确地执行此操作,或者更好地使用xpath或其他方法。。?
谢谢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源代码
If将创建一个新文档作为模板和。从不删除节点,只创建新文档并导入它们:
// 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";
}
演示:我只需创建一个新文档,其中只包含
根元素和一个“假”初始子元素:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test SYSTEM "dtd">
<root>
<fakechild />
</root>
之后,循环原始文档的子元素,并对每个子元素执行以下步骤:
- 使用
DOMDocument::importNode
- 使用根元素的
firstChild
作为第二个参数,使用导入的节点替换新文档根元素的当前子节点
- 保存新文档
(从技术上讲,在根元素中首先使用
是不必要的,简单的空白文本节点也应该这样做–但是对于空的根元素,这不会以如此直接的方式工作,因为第一个子元素将在第一次循环迭代中为您提供NULL,因此您将没有一个节点可以馈送到DOMNode::replaceChild
作为第二个参数。当然,您可以对其进行额外的检查,并对第一项使用appendChild
而不是replaceChild
,但是为什么要使内容变得更加复杂呢。)您使用的是哪个库?千万别忘了提及这样的事情!抱歉,$doc=new DOMDocument();本机PHP DOM库。我制作了两个不同的DOM:$doc=new-DOMDocument();$doc2=new-DOMDocument();并在其中销毁子节点,以获得一个没有子节点的父节点,这样我可以从第二个列表中插入子节点,保存为html,删除此子节点,插入下一个,等等。谢谢,我的问题是importNode,我想我可以直接使用另一个dom中的节点。最好替换子节点,然后追加并删除它。
// 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";
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test SYSTEM "dtd">
<root>
<fakechild />
</root>