0

私はある種の奇妙な(私には見える)問題に直面しています。NodeList があり、反復処理中に NodeList から要素を削除する必要があります。NodeList には子要素が 1 つしかないため、その要素を削除すると、NodeList には子要素がありません。理想的には、その要素の削除後に for ループが停止するはずですが、これは発生せず、for ループが 2 回目に実行されると、使用可能な子要素がない場合でも、NullPointerException が発生します。

サンプル XML :

<Order OrderNo="1">
  <Lines>
    <Line LineNo="1"/>
  </Lines>
 </Order>

サンプルコード:

    NodeList nlLine = inDoc.getElementsByTagName("Line");
    for(int cntLn = 0 ; cntLn < nlLine.getLength() ; cntLn++){

        Element elLn = (Element) nlLine.item(cntLn);

        if(//some condition){

        elLn.getParentNode().removeChild(elLn);
        cntLn--;

         }

    }

親ノードを取得してから子を削除している行で NullPointer 例外が発生しています。これに関する手がかり/リード/ヘルプはありますか?

4

4 に答える 4

1

この動作は、ループの最後の行 (cntLn--;) が原因だと思います。

リストに 1 つの子があると仮定すると、cntln=0 と length=1 で処理を開始します。これは、ループを実行することを意味します。次に、条件が true と評価されたのでノードを削除し、カウンターを -1 に減らします。その後、for ループによって cntln が再び 0 に増加し、再び開始しますが、Lines 要素のノード リストは空です!

最後の行を省略して、もう一度やり直してください ;)

とはいえ、ノード リストをループしながらノードを削除すると、副作用が予測できないため、これは重要な処理だと思います。おそらく、このループで削除する各ノードのインデックスを保存し、後で別のループで削除する方がよいでしょう。

于 2014-04-09T06:20:47.890 に答える
1

あなたのプログラムが何をするか見てみましょう。

  1. Lineノードの取得( nlLine)
  2. nlLineのサイズ (1)よりも大きいため、サイクル変数を 0 に設定すると、サイクルに入ります。
  3. 条件が真であると仮定する
  4. XML からのノードの削除 (nlLine は更新されません!)
  5. サイクル変数を減らす
  6. サイクル変数はまだ 0 (ステップ 5 のため) であり、nlLine は更新されていないため、再びサイクルに入ります (0 < 1)。
  7. elLn現時点では親を持っていないため、NPE がスローされます (XML から削除されています) 。

解決策:コードcntLn--;から除外します。elLn.getParentNode().removeChild(elLn);nodeList から実際のノードを削除しないため、nodelistの次の要素に進む必要があります。

ヒント:for通常、循環中にリストを変更するのは悪い習慣です。少し状況は異なりますが、それでも回避しようとします。メインループの後に行う必要があります。(たとえば、removeTheseループしているリストから削除したい要素を格納するリストを作成し、メイン ループが終了したらそれらを削除できます。安全で、理解しやすく、管理しやすいです。)

于 2014-04-09T06:21:08.023 に答える
0

子を削除するときは、1ずつインクリメントし、デクリメントcntLnしないでください。for ループの上限は静的であるため、for ループの状態を管理する唯一の方法は、ループ変数を変更することです。

于 2014-04-09T06:17:41.090 に答える