我有一个相当复杂的XML文档,我需要使用PHP / SimpleXML删除特定节点。我不确定我将在文档中找到它们的深度。
它的工作原理如下: 用户插入一些我需要删除的元素ID。 (这些ID指的是一个属性。)这是一个简化的示例XML文件:
<?xml version="1.0"?>
<root>
<firstlayer>
<secondlayer>
<thirdlayer>
<element id="1"/>
<element id="2"/>
<element id="3"/>
</thirdlayer>
<thirdlayer>
<element id="4"/>
<element id="5"/>
</thirdlayer>
</secondlayer>
</firstlayer>
</root>
当我不得不删除它们时,我不知道元素的位置,所以我编写了一个遍历XML文档的递归函数:
function traverseNodes($node) {
foreach($node->children() as $child) {
if($child->getName()=="element") {
// Code for finding out if node has to be deleted
if(deleteMe) {
$dom = dom_import_simplexml($child);
$dom->parentNode->removeChild($dom);
} else {
traverseNodes($child); // visit the children
}
}
else {
// do some other stuff with the rest of the nodes
// and recursively call the function
}
}
}
此功能从根节点开始并访问所有子节点。当遇到一个必须删除的节点时,它会通过使用DOM结构将其删除......但问题是:它只删除父节点的第一个兄弟节点。因此,当我想删除前一个XML文档中的元素1,3和5时,它只会删除1和5(因为它们是在相应父元素中删除的第一个元素。
我不确定问题是什么。我已经考虑过销毁$ child对象了,所以foreach-loop不能继续,但是在两行之前和之后它们是一样的
$dom = dom_import_simplexml($child);
$dom->parentNode->removeChild($dom);
我真的很感激任何想法......
答案 0 :(得分:3)
假设您的XML位于$ xmlString中,您可以使用以下内容:
$xml = new SimpleXMLElement( $xmlString );
$ids_to_delete = array( 1, 4 );
foreach ($ids_to_delete as $id) {
$result = $xml->xpath( "//element[@id='$id']" );
foreach ( $result as $node ) {
$dom = dom_import_simplexml($node);
$dom->parentNode->removeChild($dom);
}
}