【问题标题】:Remove all child nodes of a node移除一个节点的所有子节点
【发布时间】:2011-09-18 16:40:12
【问题描述】:

我有一个 DOM 文档节点。如何删除其所有子节点?例如:

<employee> 
     <one/>
     <two/>
     <three/>
 </employee>

变成:

   <employee>
   </employee>

我想删除employee的所有子节点。

【问题讨论】:

  • Employee onetwo 没有任何子节点。您是否尝试过在 DOM 中读取、更改并写出结果?
  • 我想删除一个,两个本身,因为它们是员工的孩子
  • @Peter,我认为他的意思是如果员工有onetwo 是两个实例,则删除所有子节点。 @akshay,请发布执行(或尝试)此活动的代码。我根本没有时间想出一个完整的例子来满足你的需要。
  • 已经在 Stackoverflow 上问过几次。这可能会有所帮助:stackoverflow.com/questions/321860/…。祝你好运!

标签: java xml parsing dom


【解决方案1】:

只需使用:

Node result = node.cloneNode(false);

作为文档:

Node cloneNode(boolean deep)
deep - If true, recursively clone the subtree under the specified node; if false, clone only the node itself (and its attributes, if it is an Element).

【讨论】:

  • 好主意,但我真的认为你应该写它创建节点的副本,并且要替换文件中的实际节点,还应该添加 node.getParentNode().replaceChild(result,节点);
【解决方案2】:
public static void removeAllChildren(Node node) {
    NodeList nodeList = node.getChildNodes();
    int i = 0;
    do {
        Node item = nodeList.item(i);
        if (item.hasChildNodes()) {
            removeAllChildren(item);
            i--;
        }
        node.removeChild(item);
        i++;
    } while (i < nodeList.getLength());
}

【讨论】:

    【解决方案3】:

    无需移除子节点的子节点

    public static void removeChilds(Node node) {
        while (node.hasChildNodes())
            node.removeChild(node.getFirstChild());
    }
    

    【讨论】:

    • 如果节点列表是用数组实现的,删除最后一个子节点可能比第一个子节点更有效(这需要移动数组中剩余的子节点)。
    【解决方案4】:
    public static void removeAllChildren(Node node)
    {
      for (Node child; (child = node.getFirstChild()) != null; node.removeChild(child));
    }
    

    【讨论】:

      【解决方案5】:
      private static void removeAllChildNodes(Node node) {
          NodeList childNodes = node.getChildNodes();
          int length = childNodes.getLength();
          for (int i = 0; i < length; i++) {
              Node childNode = childNodes.item(i);
              if(childNode instanceof Element) {
                  if(childNode.hasChildNodes()) {
                      removeAllChildNodes(childNode);                
                  }        
                  node.removeChild(childNode);  
              }
          }
      }
      

      【讨论】:

      • 为什么要麻烦删除子节点的子节点?仅仅移除孩子还不够吗?
      • 另外,这不能正常工作,因为你是通过索引访问来删除的,并且从小到大。所以在上面的例子中,首先删除索引 0,即&lt;one/&gt;。然后,您删除索引 1。但是,由于 &lt;one/&gt; 已被删除,&lt;two/&gt; 位于索引 0,&lt;three/&gt; 位于索引 1。因此您删除 &lt;three/&gt;,将 &lt;two/&gt; 保留在索引 0。最后,您尝试删除索引 2,但列表中只剩下一个节点,因此您会遇到异常。
      【解决方案6】:
          public static void removeAll(Node node) 
          {
              for(Node n : node.getChildNodes())
              {
                  if(n.hasChildNodes()) //edit to remove children of children
                  {
                    removeAll(n);
                    node.removeChild(n);
                  }
                  else
                    node.removeChild(n);
              }
          }
      }
      

      这将通过传入员工节点来删除节点的所有子元素。

      【讨论】:

      • 我认为如果您发送“员工”节点并删除所有子节点,他会更喜欢,在这种情况下,如果您这样做,您将删除所有员工节点。
      • 重读他的帖子后我意识到我的错误,感谢RMT指出它
      • 为什么要递归地删除其他孩子呢?我没有在问题中看到任何表明这样做的理由。
      • 另外,这不会编译。必须非常小心地对其进行修改以进行编译,以免犯与 leoismyname 的答案相同的错误。
      • Node#getChildNodes() 不能与 Java 的 foreach 循环一起使用,因为 Node#getChildNodes() 返回的 NodeList 没有实现 java.lang.Iterable 接口。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-06
      • 1970-01-01
      相关资源
      最近更新 更多