I want to delete the empty nodes from an XML element. This xml is generated from a vendor and i dont have control on xml generation. But since the XML has few empty nodes i need to delete those empty nodes recursively.
This xml is got from OMElement and i get an Element from this object using [XMLUtils][1] Sample XML
<A>
<B>
<C>
<C1>
<C11>something</C11>
<C12>something</C12>
</C1>
</C>
<D>
<D1>
<D11>
<D111 operation="create">
<Node>something else</Node>
</D11>
</D11>
</D1>
<D2>
<D21>
</D21>
</D2>
</D>
</B>
</A>
Since D21 is an empty node i want to delete D21 and since now D2 is an empty node i want to delete D2 but since D has D1 i dont want to delete D.
Similarly it is possible that i can get
<A>
<B>
<C>
</C>
</B>
</A>
Now since C is empty i want to delete C and then B and then eventually node A. I am trying to do this using removeChild() method in Node
But so far i am unable to remove them recursively. Any suggestions to remove them recursively?
I am recursively trying to get node and node length. But node length is of no help
if(childNode.getChildNodes().getLength() == 0 ){
childNode.getParentNode().removeChild(childNode);
}
Regards
Dheeraj Joshi
I don't have enough rep to comment on @Adam's solution, but I was having an issue where after a node removal, the last sibling of that node was moved to index zero, causing it to not fully remove empty elements. The fix was to use a list to hold all of the nodes we want to recursively call for removal.
Also, there was a bug that removed empty elements that had attributes.
Solution to both issues:
public static void removeEmptyNodes(Node node) {
NodeList list = node.getChildNodes();
List<Node> nodesToRecursivelyCall = new LinkedList();
for (int i = 0; i < list.getLength(); i++) {
nodesToRecursivelyCall.add(list.item(i));
}
for(Node tempNode : nodesToRecursivelyCall) {
removeEmptyNodes(tempNode);
}
boolean emptyElement = node.getNodeType() == Node.ELEMENT_NODE
&& node.getChildNodes().getLength() == 0;
boolean emptyText = node.getNodeType() == Node.TEXT_NODE
&& node.getNodeValue().trim().isEmpty();
if (emptyElement || emptyText) {
if(!node.hasAttributes()) {
node.getParentNode().removeChild(node);
}
}
}