我遍历一个大的xml文档,我需要删除一些节点。不幸的是,我的foreach在第一次移除后断了那怎么样?
$ids = [1, 2];
$data=<<<DNS_TXT
<feed xmlns:g="http://base.google.com/ns/1.0">
<entry><g:id>1</g:id><description>Desc 1</description></entry>
<entry><g:id>2</g:id><description>Desc 2</description></entry>
<entry><g:id>3</g:id><description>Desc 3</description></entry>
<entry><g:id>4</g:id><description>Desc 4</description></entry>
<entry><g:id>5</g:id><description>Desc 5</description></entry>
</feed>
DNS_TXT;
$doc = new SimpleXMLElement($data);
$i = 0;
foreach($doc->entry as $entry)
{
$i++;
$dom = $entry->children('http://base.google.com/ns/1.0');
if(!in_array($dom->id, $ids)) {
$dom = dom_import_simplexml($entry);
$dom->parentNode->removeChild($dom);
}
}
echo $i;
结果是3而不是5 ......
当然,我可以这样做:
/.../
$toRemove = array();
foreach($doc->entry as $entry)
{
$dom = $entry->children('http://base.google.com/ns/1.0');
if(!in_array($dom->id, $ids)) {
$dom = dom_import_simplexml($entry);
$toRemove[] = $dom;
}
}
foreach ($toRemove as $dom) {
$dom->parentNode->removeChild($dom);
}
/.../
但是为什么在第一种情况下foreach会结束?
答案 0 :(得分:0)
以这种方式从最大索引循环到最低索引更好。所以它有效:
$entries = $doc->entry;
for($i = count($entries)-1; $i >= 0; $i--)
{
$entry = $entries[$i];
$dom = $entry->children('http://base.google.com/ns/1.0');
if(!in_array($dom->id, $ids)) {
unset($doc->entry[$i]);
}