【问题标题】:For Loop iterated twice even when size of NodeList is 1即使 NodeList 的大小为 1,For 循环也会迭代两次
【发布时间】:2014-04-09 06:01:37
【问题描述】:

我正面临某种奇怪的(在我看来)问题。我有一个 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 异常。对此有任何线索/线索/帮助吗?

【问题讨论】:

  • 您的inDoc 指向哪个标签?它应该指向Lines,而不是Order。顺便说一句,DOM 将空格、制表符和换行符视为一个单独的节点,因此请从 XML 文件中删除所有空格、制表符和换行符

标签: loops for-loop removechild xmlnodelist


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    我认为这种行为是由循环的最后一行 (cntLn--;) 引起的。

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

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

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

    【讨论】:

      【解决方案3】:

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

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

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 2014-05-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-08-18
          • 1970-01-01
          • 2010-12-28
          • 2011-08-16
          • 2017-10-13
          相关资源
          最近更新 更多