PHP SimpleXML - 在foreach循环中取消设置节点时,节点不再存在

时间:2014-07-26 07:59:16

标签: php foreach simplexml

我有包含项目的SimpleXML对象,这些项目具有非唯一ID和版本。我要做的是删除相同ID的旧版本。

这是一个粗略的XML模型:

<results>
    <result>
        <guid></guid>
        <version></version>
    </result>
    <result>
        <guid></guid>
        <version></version>
    </result>
</results>

这是我的代码:

$items_iterator = $items;

foreach($items_iterator->xpath("result") as $i_indx=>$i_item)
{
    foreach($items->xpath("result") as $k_item) 
    {    
        if((string)$k_item->guid == (string)$i_item->guid && 
            ((string)$i_item->version > (string)$k_item->version))
        {
            //reffer to: https://stackoverflow.com/a/16062633
            unset($k_item[0]);
        }

    }
}

但是,当我运行此代码时,我得到了一堆&#34;节点不再存在&#34;在包含if语句的行上。我无法弄清楚为什么会这样。我试图通过各种方式,关键或价值来解除它,但这并没有帮助。

此外,我发现this thread,但他声称是正确的取消方式的方式与我的方式完全相同。我不明白为什么我会收到这个错误。

任何建议都将不胜感激。

编辑:这是一个包含一些示例数据的PHP小提琴:http://phpfiddle.org/main/code/b1f80276a7ce7336225b

1 个答案:

答案 0 :(得分:1)

我已经找到了问题所在。

经过进一步调查,我意识到“节点不再存在”错误是指$ i_item,而不是$ k_item。

这是因为当我将$ items SimpleXML对象复制到$ items_iterator ...

$items_iterator = $items;

...而不是复制对象,它只是复制了引用。但是新的$ items_iterator仍然引用了旧的$ items。它基本上是一个别名。这种现象有很好的记录here

因此,当我取消设置$ k_item时,它也会取消设置相同的$ i_item,导致循环期间出现错误,因为它应该迭代的键不再存在。

解决方案是调用“clone"方法,它不是仅传递引用,而是将每个属性复制到新对象。

$items_iterator = clone $items;

这就是我必须做的一切。添加一个关键字。希望有一天能帮到某人。