如何使用PHP基于子节点的值删除DOM节点?

时间:2012-01-06 03:06:47

标签: php xml

我正在尝试编写一个PHP脚本,它将根据子节点的值删除节点。换句话说,我试图用XML做同样的事情,我会用关系数据库。在数据库中,我会删除在第1列和第3列中具有“否”的所有行。在XML中,如果我的每个节点都有三个子节点,我想删除具有第一个和第三个子节点的所有节点“否”。

很容易找到子节点满足上述要求的父节点。诀窍是然后删除父节点(及其所有子节点)而不会抛出致命错误。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

发布此问题大约一周后,我制定了一个解决方案,在此过程中,我学到了很多关于在PHP中使用XML DOM的知识。

首先,我发现,如果我对三个孩子所做的一切都在寻找它们是否包含“Y”或“N”,那么它们也可能是属性而不是元素。这样做可以减少每个“项目”元素下的子元素数量,这些元素可能更好地带有“实质性”而不是“控制”数据。这也意味着我的程序不必“挖掘”来查看每个“item”元素下的子元素。

其次,我决定包含第四个属性,我称之为“delete =”。我使用此属性标记要删除的元素。

第三,我将所有“item”元素放入NodeList并在foreach()循环中使用if语句来检查第一个和第三个属性中每个打开“item”元素标记的“N”。如果是这样,我设置delete =“Y”。

第四,我设置了第二个循环来删除标记为delete =“Y”的元素。不管你信不信,这很棘手,我很快就发现了。

我没有尝试设置只包含标记为删除的元素的NodeList,因为我不知道该怎么做。相反,我使用了上面第三步中的NodeList,其中包含所有“item”元素。我很快发现不使用for()或foreach()循环来执行实际的删除。尽管这两种循环最常用于访问NodeList中的各个节点,但它们在删除节点时会产生问题。这是因为,当您移除节点时,NodeList的长度会自动缩短,因此,如果删除第25个位置中的元素,则位于第26个位置的元素将移动到第25个位置,等等。然而,for()或foreach()循环中的计数器将无情地移动到第26位,跳过对移动元素的检查。

我通过设置while {}循环解决了这个难题,如下面的PHP程序段所示,其中$ items是NodeList,$ root是XML文档的根元素:

    $i=0;
    while($i<$items->length)
    {
    $y=$items->item($i);

    /*If you delete an element node, you do not increment the index, $i,
    because another element will move into the ith position and 
    you will have skipped that element.*/

    if ($delete=="Y")
$root->removeChild($y);

    //otherwise, you increment $i.
else
$i=$i+1; 
    }