使用PHP SimpleXML从XML文档中删除多个兄弟节点

时间:2012-01-26 13:48:48

标签: php xml simplexml

我有一个相当复杂的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);

我真的很感激任何想法......

1 个答案:

答案 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);
    }
}