1

我有以下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。当我下次运行脚本时,它会删除一条记录,下一次删除一条记录。所以这就是所有五条记录都被删除的方式。为什么会这样?

我希望它们一次全部删除。请帮忙。

4

2 回答 2

2

foreach与从 a 中删除元素结合使用很麻烦DOMNodeList。当元素被删除时,列表会就地更改,但foreach不会对此进行补偿。

DOM 中的 NodeList 和 NamedNodeMap 对象是活动的;也就是说,对底层文档结构的更改会反映在所有相关的 NodeList 和 NamedNodeMap 对象中。

DOM 结构模型

两种常见的方法是:

  1. 构建要移除的元素集合,然后移除它们

    foreach ($conv as $conversation) 
    {
        if ($conversation->getAttribute('email') == $this->adminEmail) 
        {
            $to_delete[] = $conversation;
        }
    }
    
    foreach ($to_delete as $conversation)
    {
        $conversation->parentNode->removeChild($conversation);
    }
    
  2. 从列表中删除第一个元素,直到不再有

    $conv = $xpath->query('/server/conversation[@email="'.$this->adminEmail.'"]');
    while ($conv->length > 0)
    {
        $conv->item(0)->parentNode->removeChild($conv->item(0));
    }
    
于 2012-08-07T18:38:02.027 回答
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();
}
于 2012-08-07T18:27:16.600 回答