Java HTML / XML How to - Remove empty XML elements








Question

We would like to know how to remove empty XML elements.

Answer

//from   w  ww. j a  v a2  s .  co  m
import java.io.File;
import java.util.LinkedList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class Main {

  public static void main(String[] args) throws Exception {
    DocumentBuilder builder = DocumentBuilderFactory.newInstance()
        .newDocumentBuilder();
    Document doc = builder.parse(new File("test1.xml"));

    removeEmptyChildElements(doc.getDocumentElement());

    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    Transformer transformer = transformerFactory.newTransformer();
    DOMSource source = new DOMSource(doc);
    StreamResult result = new StreamResult(new File("clean.xml"));
    transformer.transform(source, result);
  }

  private static void removeEmptyChildElements(Element parentElement) {
    List<Element> toRemove = new LinkedList<Element>();

    NodeList children = parentElement.getChildNodes();
    int childrenCount = children.getLength();
    for (int i = 0; i < childrenCount; ++i) {
      Node child = children.item(i);
      if (child.getNodeType() == Node.ELEMENT_NODE) {
        Element childElement = (Element) child;
        removeEmptyChildElements(childElement);
        if (elementIsRedundant(childElement)) {
          toRemove.add(childElement);
        }
      }
    }

    for (Element childElement : toRemove) {
      parentElement.removeChild(childElement);
    }
    parentElement.normalize();
  }

  private static boolean elementIsRedundant(Element element) {
    if (element.hasAttributes())
      return false;
    if (!element.hasChildNodes())
      return true;
    NodeList children = element.getChildNodes();
    int childrenCount = children.getLength();
    for (int i = 0; i < childrenCount; ++i) {
      Node child = children.item(i);
      String value = child.getNodeValue();
      if (value != null && !value.matches("\\s*")) {
        return false; // Found non-whitespace text
      }
    }
    return true;
  }
}