从xml中删除节点不完整,需要多次运行

时间:2013-09-19 14:00:18

标签: xml dom

我有一个非常奇怪的错误,我想弄清楚。我加载一个xml,找到一个特定的节点,然后删除它,然后保存该文件。但是当我运行它时,它只会在第一次运行时捕获一些节点,然后在第二次和第三次运行时捕获更多节点,直到它最终完成。我无法理解为什么会这样。这是我的代码:

foreach(glob("*.xml") as $filename) {
$domsrc = file_get_contents($filename, FILE_TEXT);
$MYdom = new DomDocument();
$MYdom->loadXML($domsrc);

foreach ($MYdom->getElementsByTagName('URL') as $virttour) {
    if($virttour->getAttribute('Type') == 'Virtual Tour') {
$virttour->parentNode->removeChild($virttour); 
   }
}
$MYdom->save($filename);

2 个答案:

答案 0 :(得分:0)

我仍然不知道造成这种情况的原因,但我以不同的方式重新编写代码,现在它正确地捕获了所有内容:

foreach(glob("*.xml") as $filename) {
$domsrc = file_get_contents($filename, FILE_TEXT);
$MYdom = new DomDocument();
$MYdom->loadXML($domsrc);
$xpath = new DOMXPath($MYdom);
$nodeList = $xpath->query('//URL[@Type="Virtual Tour"]');

foreach ($nodeList as $node){
if ($nodeList->length>0) {
        $node->parentNode->removeChild($node);
    }
}
$MYdom->save($filename);

再一次,没有IDEA为什么它不能一次性使用其他代码,但希望这会帮助其他可能遇到类似问题的人。

答案 1 :(得分:0)

您的第一段代码无效的原因是因为节点列表或$ MYdom-> getElementsByTagName('URL')创建的列表是动态的。这意味着当您删除元素时,它会更改节点的长度及其位置。 foreach语句最终会跳过元素,因为它们的位置发生了变化。完成原始语句的最佳方法是使用for语句来考虑这一点:

$nodes = $MYdom->getElementsByTagName('URL')

for ($i = 0; $i < $nodes->length; $i++) {
                  $node = $nodes->item($i);
                  $node->parentNode->removeChild($node);
                  $i--;
                }

或暂时声明:

while($nodes->length) {
                  $node = $FlavorNodes->item(0);
                  $node->parentNode->removeChild($node);
                }