我有包含项目的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
答案 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;
这就是我必须做的一切。添加一个关键字。希望有一天能帮到某人。