-1

是否可以从 xml 文档中删除 n 个 xml 元素,以便

<root>
<example>
<thing>1</thing>
<somethingelse>1</somethingelse>
</example>
<example>
<thing>2</thing>
<somethingelse>2</somethingelse>
</example>
<example>
<thing>3</thing>
<somethingelse>3</somethingelse>
</example>
</root>

可能成为

<root>
<example>
<thing>3</thing>
<somethingelse>3</somethingelse>
</example>
</root>

例如 xml_splice($xml,2,3)

搜索文档后,我找不到在 simpleXML 中执行此操作的简单方法,但还有其他我可以使用的方法吗?还是我坚持使用 $xmlIterator->next(); 编写自己的函数?

提前致谢

4

1 回答 1

1

在您的情况下,我不会使用 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 的变体,请参阅我在相关问题中的回答:

于 2013-04-17T14:39:24.543 回答