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です。次回スクリプトを実行すると、1つのレコードが削除され、次に1つのレコードが削除されます。これにより、5つのレコードすべてが削除されます。なぜこれが発生するのでしょうか。

それらすべてを一度に削除してほしい。助けてください。

4

2 に答える 2

2

foreachから要素を削除することと組み合わせて使用​​するのは面倒DOMNodeListです。要素が削除されると、リストはその場で変更されますが、foreachそれを補正することはありません。

DOM内のNodeListオブジェクトとNamedNodeMapオブジェクトはライブです。つまり、基になるドキュメント構造への変更は、関連するすべてのNodeListオブジェクトとNamedNodeMapオブジェクトに反映されます。

–DOM構造モデル

2つの一般的なアプローチは次のとおりです。

  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 に答える