0

我正面临某种奇怪的(在我看来)问题。我有一个 NodeList,需要在迭代时从 NodeList 中删除一个元素。NodeList 只有一个子元素,因此删除该元素后 NodeList 没有任何子元素。理想情况下,for 循环应该在删除该元素后停止,但这并没有发生,并且当 for 循环第二次运行时,即使没有可用的子元素,我也会收到 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--;)引起的。

假设该列表有一个孩子,因此您以 cntln=0 和 length=1 开始处理,这意味着:执行循环。然后删除节点,因为条件被评估为真,并将计数器减少到 -1。之后,您的 for 循环再次将 cntln 增加到 0 并重新开始,但现在 Lines 元素的节点列表为空!

只需省略最后一行,然后再试一次;)

尽管如此,我认为这是一个关键处理,因为在遍历节点列表时删除节点时您无法预见副作用。也许在这个循环中存储要删除的每个节点的索引并稍后在另一个循环中删除它们会更好。

于 2014-04-09T06:20:47.890 回答
1

让我们看看你的程序做了什么。

  1. 获取Line节点 ( nlLine)
  2. 将循环变量设置为 0,因为它大于nlLine的大小 (1),我们将进入循环。
  3. 假设条件为真
  4. 从 XML 中删除节点(nlLine 未更新!)
  5. 递减循环变量
  6. 循环变量仍然是 0(因为第 5 步。)并且 nlLine 还没有更新,所以我们再次进入循环(0 < 1)
  7. 由于elLn此时没有父级 NPE 将被抛出(它已从 XML 中删除)

解决方案:cntLn--;从您的代码中省略。您必须进入节点列表的下一个元素,因为elLn.getParentNode().removeChild(elLn);不会从节点列表中删除您的实际节点。

提示:for通常在循环遍历列表时修改列表是一种不好的做法。虽然情况有点不同,但还是尽量避免。您应该在主循环之后执行此操作。(例如,创建一个removeThese列表来存储要从正在循环的列表中删除的元素,一旦完成主循环,就可以将它们删除。它很安全,易于理解且易于管理。)

于 2014-04-09T06:21:08.023 回答
1

您正在递减循环变量cntLn--。我很确定你打算增加它cntLn++。而且由于您已经在增加,只需省略该行cntLn--;

提示:作为一种健康的编码实践,++cntLn在循环的情况下始终使用前缀增量运算符(除非您明确需要后缀行为)。

于 2014-04-09T06:21:33.583 回答
0

删除子项时只需递增而不是递减cntLn- for 循环的上限是静态的,因此管理 for 循环状态的唯一机会是修改循环变量。

于 2014-04-09T06:17:41.090 回答