Java XML Tutorial

How to count the depth of XML document (DOM Parser)

In the DOM parser, we can use a recursive loop of the child nodes to find or count the depth of the XML document.

Table of contents

P.S Tested with Java 11.

1. An XML file

The below XML file consists of 3 levels of depth.

src/main/resources/staff.xml

<?xml version="1.0" encoding="utf-8"?>
<company>                     <!-- Level 1 -->
    <staff id="1001">         <!-- Level 2 -->
        <name>mkyong</name>   <!-- Level 3 -->
        <role>support</role>  <!-- Level 3 -->
        <salary currency="USD">5000</salary>
        <!-- for special characters like < &, need CDATA -->
        <bio><![CDATA[HTML tag <code>testing</code>]]></bio>
    </staff>
    <staff id="1002">
        <name>yflow</name>
        <role>admin</role>
        <salary currency="EUR">8000</salary>
        <bio><![CDATA[a & b]]></bio>
    </staff>
</company>

2. DOM Parser + Recursive Loop

The below example uses a DOM parser and recursive loop to find the depth of the XML level.

CountDepthXmlDom.java

package com.mkyong.xml.dom;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class CountDepthXmlDom {

  private static final String FILENAME = "src/main/resources/staff.xml";
  private static int DEPTH_XML = 0;

  public static void main(String[] args) {

      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

      try (InputStream is = new FileInputStream(FILENAME)) {

          DocumentBuilder db = dbf.newDocumentBuilder();

          Document doc = db.parse(is);

          // get all elements
          NodeList childNodes = doc.getChildNodes();

          printNode(childNodes, 0);

          System.out.println("Depth of XML : " + DEPTH_XML);

      } catch (ParserConfigurationException | SAXException | IOException e) {
          e.printStackTrace();
      }

  }

  // loop recursive
  private static void printNode(NodeList nodeList, int level) {
      level++;

      if (nodeList != null && nodeList.getLength() > 0) {
          for (int i = 0; i < nodeList.getLength(); i++) {

              Node node = nodeList.item(i);
              if (node.getNodeType() == Node.ELEMENT_NODE) {

                  String result = String.format(
                          "%" + level * 5 + "s : [%s]%n", node.getNodeName(), level);
                  System.out.print(result);

                  printNode(node.getChildNodes(), level);

                  // how depth is it?
                  if (level > DEPTH_XML) {
                      DEPTH_XML = level;
                  }

              }

          }
      }

  }

}

Output

Terminal

company : [1]
   staff : [2]
         name : [3]
         role : [3]
       salary : [3]
          bio : [3]
   staff : [2]
         name : [3]
         role : [3]
       salary : [3]
          bio : [3]
Depth of XML : 3

3. DOM Parser + Tree Walker

The below example uses DOM’s TreeWalker to walk the nodes and find the depth of the XML level.

CountDepthXmlDomTreeWalker.java

package com.mkyong.xml.dom;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.traversal.DocumentTraversal;
import org.w3c.dom.traversal.NodeFilter;
import org.w3c.dom.traversal.TreeWalker;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class CountDepthXmlDomTreeWalker {

    private static final String FILENAME = "src/main/resources/staff.xml";
    private static int DEPTH_XML = 0;

    public static void main(String[] args) {

        int depth = countDepthXml(FILENAME);
        System.out.println("Depth of XML : " + depth);
    }

    private static int countDepthXml(String filename) {

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

        try (InputStream is = new FileInputStream(filename)) {

            DocumentBuilder db = dbf.newDocumentBuilder();

            Document doc = db.parse(is);

            DocumentTraversal traversal = (DocumentTraversal) doc;

            // DOM tree walker
            TreeWalker walker = traversal.createTreeWalker(
                    doc.getDocumentElement(),
                    NodeFilter.SHOW_ELEMENT,
                    null,
                    true);

            traverseXmlElements(walker, 0);

        } catch (ParserConfigurationException | SAXException | IOException e) {
            e.printStackTrace();
        }

        return DEPTH_XML;

    }

    private static void traverseXmlElements(TreeWalker walker, int level) {

        level++;

        Node node = walker.getCurrentNode();

        String result = String.format(
                "%" + level * 5 + "s : [%s]%n", node.getNodeName(), level);
        System.out.print(result);

        for (Node n = walker.firstChild();
             n != null;
             n = walker.nextSibling()) {
            traverseXmlElements(walker, level);
        }

        walker.setCurrentNode(node);

        // how depth is it?
        if (level > DEPTH_XML) {
            DEPTH_XML = level;
        }

    }

}

Output

Terminal

company : [1]
   staff : [2]
         name : [3]
         role : [3]
       salary : [3]
          bio : [3]
   staff : [2]
         name : [3]
         role : [3]
       salary : [3]
          bio : [3]
Depth of XML : 3

4. Download Source Code

$ git clone https://github.com/mkyong/core-java

$ cd java-xml

$ cd src/main/java/com/mkyong/xml/dom/

5. References

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
1 Comment
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Snidi
1 year ago

Such an elegant way to implement recursion !
Very helpful, thanks