2013-06-19 85 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