14

I have a node of DOM document. How can I remove all of its child nodes? For example:

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

Becomes:

   <employee>
   </employee>

I want to remove all child nodes of employee.

Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315
akshay
  • 5,235
  • 14
  • 39
  • 49
  • 1
    Employee `one` and `two` don't have any child nodes. Have you tried reading in a DOM, changing it and writing out the result? – Peter Lawrey Jun 20 '11 at 13:15
  • I want to remove one ,two itself as they are child of employee – akshay Jun 20 '11 at 13:19
  • @Peter, I think he meant removal of all child nodes if employee with `one` and `two` being two instances. @akshay, please post the code that performs (or attempts to) this activity. I simply do not have the time to conjure a full blown example that performs what you need. – Vineet Reynolds Jun 20 '11 at 13:21
  • Asked a couple of times on Stackoverflow already. This might help: http://stackoverflow.com/questions/321860/how-to-remove-elements-from-xml-using-xslt-with-stylesheet-and-xsltproc. Good luck! – Perception Jun 20 '11 at 13:22

6 Answers6

56

No need to remove child nodes of child nodes

public static void removeChilds(Node node) {
    while (node.hasChildNodes())
        node.removeChild(node.getFirstChild());
}
kop
  • 601
  • 5
  • 4
  • 1
    If the node list is implemented with an array, it might be more efficient to remove the last child than the first child (which requires shifting the remaining children in the array). – joriki May 29 '21 at 08:00
1
public static void removeAllChildren(Node node)
{
  for (Node child; (child = node.getFirstChild()) != null; node.removeChild(child));
}
Venkata Raju
  • 4,866
  • 3
  • 27
  • 36
1

Just use:

Node result = node.cloneNode(false);

As document:

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).
Google New
  • 107
  • 1
  • 1
  • 7
  • Good idea, but I really think you should write that it creates a copy of the node and that to replace the actual node in the file one should also add node.getParentNode().replaceChild(result, node); – Lavandysh Nov 19 '19 at 09:39
-1
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);  
        }
    }
}
leoismyname
  • 407
  • 6
  • 11
  • 1
    Why go through the trouble of removing the child nodes' children? Wouldn't just removing the children be enough? – Dan Getz Jun 16 '15 at 20:36
  • 2
    Also, this can't work right, because you're removing by accessing by index, and going from small to large. So in the example above, first you remove index 0, which is ``. Then, you remove index 1. However, because `` has been removed, `` is at index 0, and `` is at index 1. So you remove ``, leaving `` at index 0. Finally, you try to remove index 2, but there's only one node left in the list, so you get an exception. – Dan Getz Jun 16 '15 at 20:56
-1
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());
}
-1
    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);
        }
    }
}

This will remove all the child elements of a Node by passing the employee node in.

Hunter McMillen
  • 59,865
  • 24
  • 119
  • 170
  • I think he would prefer if you send in the "Employee" node and you just remove all children, in this case if you do that you will remove all employee nodes. – RMT Jun 20 '11 at 13:27
  • I realized my mistake after rereading his post, thanks for pointing it out RMT – Hunter McMillen Jun 20 '11 at 13:31
  • BTW, does it needs to be recursive? How this code will works on – Sergei Chicherin Jun 20 '11 at 13:36
  • I hadn't considered that, but it would be a really easy fix. I edit the solution above. – Hunter McMillen Jun 20 '11 at 13:40
  • 1
    Why go through the trouble of removing other children recursively? I don't see anything in the question that would suggest a reason to do that. – Dan Getz Jun 16 '15 at 20:38
  • 1
    Also, this doesn't compile. One must be very careful modifying it to compile, to not make the same mistake as in leoismyname's answer. – Dan Getz Jun 16 '15 at 21:01
  • 3
    [`Node#getChildNodes()`](http://docs.oracle.com/javase/7/docs/api/org/w3c/dom/Node.html#getChildNodes%28%29) cannot be used with Java's foreach loop because `Node#getChildNodes()` returns a [`NodeList`](http://docs.oracle.com/javase/7/docs/api/org/w3c/dom/NodeList.html) which does not implement the [`java.lang.Iterable`](http://docs.oracle.com/javase/7/docs/api/java/lang/Iterable.html) interface. – dbank Jun 16 '15 at 21:01
  • @DanGetz: That's true. I made this mistake myself. [kop's answer](http://stackoverflow.com/a/20810451/4595816) works, though. – dbank Jun 16 '15 at 21:16