2013-06-19 301 views
1

我有一個foreach循環,只運行一次,它讓我難倒了。SimpleXML刪除節點

1:I加載狀態值的陣列(或者「請求」,「刪除」或「購買」)

2:我然後加載XML文件,並通過「代碼」節點需要循環並更新自己的狀態,但是如果新的代碼爲「刪除」我要的是前移動到下一個

XML結構來刪除它....

<content> 
.... lots of stuff 
<codes> 
<code date="xxx" status="request">xxxxx</code> 
.. repeat ... 
</codes> 
</content> 

和PHP代碼.. 。

$newstatus = $_POST['updates']; 
$file = '../apps/templates/'.$folder.'/layout.xml'; 
$xml2 = simplexml_load_file($file); 
foreach($xml2->codes->code as $code){ 
    if($code['status'] == "delete") { 
     $dom=dom_import_simplexml($code); 
     $dom->parentNode->removeChild($dom); 
    } 
} 
$xml2->asXml($file); 

我暫時刪除了更新,因此我可以調試刪除檢查。 這一切工作,但它只刪除第一次刪除,並保留所有其他刪除,即使它是一個foreach循環??。 任何幫助非常感謝。

+0

重複的問題,檢查答案在http://stackoverflow.com/questions/3418197/how-to-remove-a-node-if-it-exists-with-simplexml?rq=1。 –

+0

這很可能是您從[[(現在)接受的答案](http://stackoverflow.com/a/262556/367456)的[代碼]中複製了此代碼* [在SimpleXML中刪除具有特定屬性的子代, PHP(http://stackoverflow.com/q/262351/367456)*。問題在於,給出的答案是不穩定的。該代碼的問題在於,它僅在刪除迭代器發生更改後才寫入單個刪除。您需要首先通過'iterator_to_array'將其轉換爲數組,或者通過使用xpath來指定simplexml。 http://stackoverflow.com/a/16062633/367456 – hakre

回答

13

在同一次迭代中刪除多次是不穩定的。例如。如果您刪除第二個元素,第三個元素變成第二個元素,依此類推。

您可以防止通過存儲元件刪除到數組第一:

$elementsToRemove = array(); 
foreach ($xml2->codes->code as $code) { 
    if ($code['status'] == "delete") { 
     $elementsToRemove[] = $code; 
    } 
} 

然後刪除基於其穩定的陣列上的元素,而你遍歷它:

foreach ($elementsToRemove as $code) { 
    unset($code[0]); 
} 

您也可以將if條件放入xpath查詢中,該查詢直接返回數組(請參閱the duplicate question作爲示例)或使用iterator_to_array()

+1

這是一個非常有用的答案。在這種情況下,我已經兩次了,這兩次都救了我。也許下次我可能真的記得它... – PaulSkinner

+0

謝謝你,這與代碼這樣的工作。 ** $ xml = new SimpleXMLElement($ rs_xml); $ elementsToRemove = array(); foreach($ xml-> channel-> item as $ element){ if($ element-> guid ==「http://www.example.com/?p=2385281」){ $ elementsToRemove [] = $元素; } } foreach($ elementsToRemove as $ code){ unset($ code [0]); } ** – ziggrat