2012-01-06 62 views
0

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

找到满足上述要求的子节点的父节点很容易。诀窍是然后删除父节点(和他们的所有孩子),而不会引发致命错误。

任何想法?

+0

你在使用什么DOM库? SimpleXML的? DOM文档? – 2012-01-06 03:21:28

+0

你可以使用DOMDocument类来做到这一点。 – satrun77 2012-01-06 03:24:15

+0

当删除DOMNodeList中的所有节点时,最简单的方法是重复删除列表中的* first *项(“item(0)”),直到列表为空。 – salathe 2012-01-07 23:20:45

回答

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个位置,跳过对移动元素的检查。

我解决这个困难得到了通过建立,而{}循环如下面的PHP程序段,其中$项目是节点列表,和$ 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; 
    }