節點

2010-06-20 40 views
0

的刪除父我有XML,結構類似這樣的節點

<element> 
    <x> 
     <y> 
      <z>Value</z> 
     </y> 
    </x> 
</element> 

我選擇XML所有<z>標籤都有效這個XPath查詢 - //*[name()='z']

然後我與每個發現節點工作,如果它不滿足一些要求需要刪除整個X標籤(祖父母,如果你喜歡:))。

foreach ($x->query("//*[name()='z']") as $elm) 
{ 

if ($elm !== good) 
{ 

//need to delete whole X-tag here 

} 


} 

那麼,我該怎麼做呢?

回答

1

也許

$elm->parentNode->parentNode->parentNode-> 
    removeChild($elm->parentNode->parentNode); 

順便說一句,你可以使用

foreach ($x->query("//z") as $elm) 

代替。

+0

是的,我知道如何使用 「parentNode」。這很奇怪,但是這個代碼'$ elm-> parentNode-> parentNode-> parentNode-> removeChild($ elm-> parentNode-> parentNode);'打破了foreach。例如,我有六個'榆樹',其中第4和第6個「不好」。當foreach循環到達第4個元素時,它刪除整個「X」標籤,但是,循環是中斷。第5和第6個元素被忽略。 這很有趣,因爲這個代碼'$ elm-> parentNode-> removeChild($ elm);' - 工作完美。事實上,這就是我寫這篇文章的原因。有任何想法嗎?也許這是PHP的錯誤? – nukl 2010-06-21 00:28:37

+0

呵呵,它用這個代碼: '$ temp1 = $ elm-> parentNode-> parentNode-> parentNode; $ temp2 = $ elm-> parentNode-> parentNode; $ temp1-> removeChild($ temp2);' – nukl 2010-06-21 00:38:04

+0

@cru你說得對,我甚至會說你應該把這個刪除工作推遲到循環之後。 – Artefacto 2010-06-21 01:22:38

0

我認爲你們在一起討論兩個班級的方法。

SimpleXMLElement::removeChild不存在(它是DOMNode的一部分)。不幸的是,DOMDocument::xpath也不存在,所以你不能使用任何一個而不修改你的代碼。

我選擇DOMDocument因爲你的DOM的選擇(只需要通過標籤名稱的元素)的簡單的,這裏是我的結果:

<?php 

    $bad = 'Value'; 
    $doc = DOMDocument::load('./xpath_del.xml') or die('Failed parsing XML'); 
    $x = $doc->getElementsByTagName('x'); 

    for ($i = 0; $i < $x->length; ++$i) { 
     $z = $x->item($i)->getElementsByTagName('z'); 
     for ($j = 0; $j < $z->length; ++$j) { 
      if ($bad === $z->item($i)->nodeValue) { 
       $x->item($i)->parentNode->removeChild($x->item($j)); 
       break; 
      } 
     } 
    } 

?> 

因此,使用轉換爲SimpleXMLElement用於調試的目的(因爲我之前和之後

var_dump(simplexml_import_dom($doc)); 

輸出DOMDocument結構:「M懶得寫的方法來遍歷DOMNode S IN的DOMDocument)。請記住,如果這是針對高流量的站點,我絕對建議不要將此調試代碼放入(但這對您而言可能無關緊要)。

無論如何,這裏有結果前:

object(SimpleXMLElement)#2 (1) { 
    ["x"]=> 
    object(SimpleXMLElement)#3 (1) { 
    ["y"]=> 
    object(SimpleXMLElement)#4 (1) { 
     ["z"]=> 
     string(5) "Value" 
    } 
    } 
} 

而經過:

object(SimpleXMLElement)#5 (0) { 
} 

嘗試一下自己,;)

+0

只是重新閱讀問題,重新格式化,舉行 – 2010-06-21 03:49:43

+0

這也假設你有一個名爲「xpath_del」的文件。xml「與您在同一目錄中列出的相同結構,btw ... – 2010-06-21 04:03:37