2012-01-06 39 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; 
    }