我有以下xml:
<?xml version="1.0" encoding="utf-8"?>
<server>
<gcm regId="APA91-yySYdx_Ydvkl2pQNB54yDpJRq4SnWvJCpsaCm6hT3LlXqP1S-3uTiXlXwylPKmrFSZbsA" email="mozi"/>
<conversation ip="mozi1" email="mozi">
<chat>abc</chat>
</conversation>
<conversation ip="mozi1" email="mozi">
<chat>abc</chat>
</conversation>
<conversation ip="mozi1" email="mozi">
<chat>abc</chat>
</conversation>
<conversation ip="mozi1" email="mozi">
<chat>abc</chat>
</conversation>
<conversation ip="mozi1" email="mozi">
<chat>abc</chat>
</conversation>
</server>
我想删除conversation
所有email=mozi
个标签。
我是通过以下代码完成的。
public function DeleteConversation()
{
$conv=$this->xmlDom->getElementsByTagName("conversation");
foreach ($conv as $conversation)
{
if ($conversation->getAttribute('email') == $this->adminEmail)
{
$this->xmlDom->documentElement->removeChild($conversation);
}
}
$this->SaveChanges();
}
现在,当我运行脚本并调用此函数时。循环只能工作3次。它只删除3 records
。当我下次运行脚本时,它会删除一条记录,下一次记录一条记录。这就是所有五条记录都被删除的原因。为什么会发生这种情况?
我希望他们一次性删除。请帮忙。
答案 0 :(得分:2)
使用foreach
结合删除DOMNodeList
中的元素很麻烦。删除元素后,列表会就地更改,但foreach
不会对此进行补偿。
DOM中的NodeList和NamedNodeMap对象是实时的;也就是说,对底层文档结构的更改将反映在所有相关的NodeList和NamedNodeMap对象中。
两种常见的方法是:
构建要删除的元素集合,然后将其删除
foreach ($conv as $conversation)
{
if ($conversation->getAttribute('email') == $this->adminEmail)
{
$to_delete[] = $conversation;
}
}
foreach ($to_delete as $conversation)
{
$conversation->parentNode->removeChild($conversation);
}
从列表中删除第一个元素,直到不再有
$conv = $xpath->query('/server/conversation[@email="'.$this->adminEmail.'"]');
while ($conv->length > 0)
{
$conv->item(0)->parentNode->removeChild($conv->item(0));
}
答案 1 :(得分:0)
我认为这是因为你操纵了你正在循环的集合。尝试创建数组的副本,如下所示:
public function DeleteConversation()
{
$conv=$this->xmlDom->getElementsByTagName("conversation");
$copy = $conv;
foreach ($copy as $conversation)
{
if ($conversation->getAttribute('email') == $this->adminEmail)
{
$this->xmlDom->documentElement->removeChild($conversation);
}
}
$this->SaveChanges();
}