在您的情况下,我不会使用 simplexml 迭代器,因为您遇到的问题是,当您在迭代它时删除一个元素时,迭代会随着元素节点的消失而中断。因此,在删除第一个元素后,第二个元素成为第一个元素。然后迭代器转到第二个,现在已经是第三个了。
相反,您可以将第一个元素删除两次:
$xml = simplexml_load_string($string);
for ($remove = 2; $remove--;)
{
unset($xml->example[0]);
}
这会给你:
<?xml version="1.0"?>
<root>
<example>
<thing>3</thing>
<somethingelse>3</somethingelse>
</example>
</root>
这种方法的问题是你不能概括它。最好先创建一个包含要删除的元素的数组,然后遍历该数组并一个接一个地删除一个元素。
使用 simplexml 创建这样一个数组的一种简单方法是iterator_to_array()
或者SimpleXMLElement::xpath()
方法。当您xml_splice()
在问题中用作模拟时,我假设您想先查看数组变体:
$examples = $xml->example;
$elements = iterator_to_array($examples, false);
array_splice($elements, 2, 3);
这会将所有应该删除的示例$elements
元素放入. 剩下要做的就是删除那些。在 SimpleXML 中,这需要一个 simplexmlelement-self-reference:
foreach($elements as $element)
{
unset($element[0]);
}
如您所见,$element
要从文档中删除节点$xml
,它的第一个偏移量 ( 0 ) 未设置。如果你想在它之后添加一个var_dump:
unset($element[0]);
var_dump($element);
您会看到此警告,显示元素节点已被删除:
警告:var_dump():节点不再存在
输出就像您现在可能预期的那样:
<?xml version="1.0"?>
<root>
<example>
<thing>3</thing>
<somethingelse>3</somethingelse>
</example>
</root>
对于带有 xpath 的变体,请参阅我在相关问题中的回答: