Skip to content

XML Parsing in Java — Complete Guide with DOM, SAX, and StAX

DodaTech Updated 2026-06-23 9 min read

In this tutorial, you'll learn about XML Parsing in Java. We cover key concepts, practical examples, and best practices.

XML parsing in Java provides four main approaches — DOM, SAX, StAX, and JAXB — each suited to different scenarios from in-memory document manipulation to streaming processing of large files and object-to-XML binding.

What You'll Learn

  • Parsing XML with DOM (Document Object Model) for in-memory access
  • Using SAX (Simple API for XML) for event-driven streaming
  • StAX (Streaming API for XML) for pull-based parsing
  • JAXB for automatic Java object to XML mapping
  • Choosing the right parser for your use case

Why XML Parsing in Java Matters

Java has built-in XML processing since JDK 1.4, making it one of the most robust platforms for enterprise XML handling. From Android app layouts to financial data interchange, Java XML parsers are everywhere. Doda Browser uses Java XML parsers to process browser configuration profiles and bookmark files during its Android build.

Learning Path

flowchart LR
  A[XML Basics] --> B[XML Parsing Python]
  B --> C[XML Parsing Java
You are here] C --> D[XML Parsing JavaScript] D --> E[XML Schema XSD]

Sample XML Data

<?xml version="1.0" encoding="UTF-8"?>
<library>
    <book category="fiction" id="b1">
        <title>The Hobbit</title>
        <author>J.R.R. Tolkien</author>
        <year>1937</year>
        <price currency="USD">12.99</price>
    </book>
    <book category="non-fiction" id="b2">
        <title>A Brief History of Time</title>
        <author>Stephen Hawking</author>
        <year>1988</year>
        <price currency="GBP">9.99</price>
    </book>
    <book category="fiction" id="b3">
        <title>1984</title>
        <author>George Orwell</author>
        <year>1949</year>
        <price currency="USD">10.99</price>
    </book>
</library>

DOM Parsing

DOM loads the entire XML tree into memory, providing full navigation:

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.*;

public class DomParserExample {
    public static void main(String[] args) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse("library.xml");

        // Root element
        Element root = doc.getDocumentElement();
        System.out.println("Root: " + root.getNodeName());

        // Get all books
        NodeList books = doc.getElementsByTagName("book");
        System.out.println("Number of books: " + books.getLength());

        // Iterate through books
        for (int i = 0; i < books.getLength(); i++) {
            Element book = (Element) books.item(i);
            String title = book.getElementsByTagName("title").item(0).getTextContent();
            String author = book.getElementsByTagName("author").item(0).getTextContent();
            String year = book.getElementsByTagName("year").item(0).getTextContent();
            String price = book.getElementsByTagName("price").item(0).getTextContent();
            String category = book.getAttribute("category");

            System.out.printf("'%s' by %s (%s) - $%s [%s]%n",
                              title, author, year, price, category);
        }
    }
}

Expected output:

Root: library
Number of books: 3
'The Hobbit' by J.R.R. Tolkien (1937) - $12.99 [fiction]
'A Brief History of Time' by Stephen Hawking (1988) - $9.99 [non-fiction]
'1984' by George Orwell (1949) - $10.99 [fiction]

SAX Parsing

SAX is event-driven and memory-efficient for large files:

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;

public class SaxParserExample {
    public static void main(String[] args) throws Exception {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser saxParser = factory.newSAXParser();

        DefaultHandler handler = new DefaultHandler() {
            boolean inTitle = false;
            boolean inAuthor = false;
            String currentTitle = "";
            String currentAuthor = "";

            public void startElement(String uri, String localName,
                                     String qName, Attributes attrs) {
                if (qName.equals("title")) inTitle = true;
                if (qName.equals("author")) inAuthor = true;
                if (qName.equals("book")) {
                    currentTitle = "";
                    currentAuthor = "";
                }
            }

            public void characters(char[] ch, int start, int length) {
                String text = new String(ch, start, length).trim();
                if (inTitle) currentTitle += text;
                if (inAuthor) currentAuthor += text;
            }

            public void endElement(String uri, String localName, String qName) {
                if (qName.equals("title")) inTitle = false;
                if (qName.equals("author")) inAuthor = false;
                if (qName.equals("book")) {
                    System.out.println("Book: " + currentTitle +
                                       " by " + currentAuthor);
                }
            }
        };

        saxParser.parse("library.xml", handler);
    }
}

Expected output:

Book: The Hobbit by J.R.R. Tolkien
Book: A Brief History of Time by Stephen Hawking
Book: 1984 by George Orwell

StAX Parsing (Streaming API)

StAX gives you pull-based control — you advance the cursor manually:

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamConstants;
import java.io.FileInputStream;

public class StaxParserExample {
    public static void main(String[] args) throws Exception {
        XMLInputFactory factory = XMLInputFactory.newInstance();
        XMLStreamReader reader = factory.createXMLStreamReader(
            new FileInputStream("library.xml"));

        String currentElement = "";
        String title = "", author = "", year = "", price = "";
        boolean inBook = false;

        while (reader.hasNext()) {
            int event = reader.next();

            switch (event) {
                case XMLStreamConstants.START_ELEMENT:
                    currentElement = reader.getLocalName();
                    if (currentElement.equals("book")) {
                        inBook = true;
                        title = author = year = price = "";
                    }
                    break;

                case XMLStreamConstants.CHARACTERS:
                    String text = reader.getText().trim();
                    if (!text.isEmpty() && inBook) {
                        switch (currentElement) {
                            case "title":  title  = text; break;
                            case "author": author = text; break;
                            case "year":   year   = text; break;
                            case "price":  price  = text; break;
                        }
                    }
                    break;

                case XMLStreamConstants.END_ELEMENT:
                    if (reader.getLocalName().equals("book")) {
                        System.out.printf("%s by %s (%s) $%s%n",
                                          title, author, year, price);
                        inBook = false;
                    }
                    break;
            }
        }
        reader.close();
    }
}

Expected output:

The Hobbit by J.R.R. Tolkien (1937) $12.99
A Brief History of Time by Stephen Hawking (1988) $9.99
1984 by George Orwell (1949) $10.99

JAXB — Java Architecture for XML Binding

JAXB maps XML directly to Java objects with annotations:

import javax.xml.bind.annotation.*;
import javax.xml.bind.*;
import java.util.List;

// Java class mapped to XML
@XmlRootElement(name = "library")
class Library {
    private List<Book> books;

    @XmlElement(name = "book")
    public List<Book> getBooks() { return books; }
    public void setBooks(List<Book> books) { this.books = books; }
}

@XmlAccessorType(XmlAccessType.FIELD)
class Book {
    @XmlAttribute
    private String category;

    @XmlAttribute
    private String id;

    private String title;
    private String author;
    private int year;
    private double price;

    @XmlAttribute(name = "currency")
    private String priceCurrency;
}

// Unmarshalling (XML to Java)
public class JaxbExample {
    public static void main(String[] args) throws Exception {
        JAXBContext context = JAXBContext.newInstance(Library.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();

        Library library = (Library) unmarshaller.unmarshal(
            new java.io.File("library.xml"));

        for (Book book : library.getBooks()) {
            System.out.println("Title: " + book.getTitle());
        }
    }
}

Expected output:

Title: The Hobbit
Title: A Brief History of Time
Title: 1984

Creating XML with Java

DOM also builds XML documents:

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.*;

public class CreateXmlExample {
    public static void main(String[] args) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.newDocument();

        // Root element
        Element root = doc.createElement("library");
        doc.appendChild(root);

        // Book element with attribute
        Element book = doc.createElement("book");
        book.setAttribute("category", "fiction");
        root.appendChild(book);

        // Child elements
        Element title = doc.createElement("title");
        title.setTextContent("Dune");
        book.appendChild(title);

        Element author = doc.createElement("author");
        author.setTextContent("Frank Herbert");
        book.appendChild(author);

        Element year = doc.createElement("year");
        year.setTextContent("1965");
        book.appendChild(year);

        // Write to file
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.setOutputProperty(javax.xml.transform.OutputKeys.INDENT, "yes");
        DOMSource source = new DOMSource(doc);
        StreamResult result = new StreamResult(new java.io.File("output.xml"));
        transformer.transform(source, result);

        System.out.println("XML created successfully.");
    }
}

Expected output:

XML created successfully.

And the resulting output.xml:

<?xml version="1.0" encoding="UTF-8"?>
<library>
    <book category="fiction">
        <title>Dune</title>
        <author>Frank Herbert</author>
        <year>1965</year>
    </book>
</library>

Security Angle

Java XML parsers are vulnerable to XXE and entity expansion attacks by default. Always configure secure parsing:

import javax.xml.parsers.DocumentBuilderFactory;

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

// Secure configuration
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("untrusted.xml");

Durga Antivirus Pro for Android uses these exact security configurations when parsing threat signature XMLs received over the network, preventing XXE-based attacks from compromised update servers.

Parser Comparison

Feature DOM SAX StAX JAXB
Memory High (full tree) Low (streaming) Low (streaming) Medium
Access Random (any node) Sequential Sequential (pull) Object-oriented
Speed Moderate Fast Fast Moderate
Ease of use Easy Moderate Moderate Very easy
Best for Small docs, modifications Large docs, extraction Large docs, control Object binding

Common Mistakes

1. Not wrapping parse exceptions properly

XML parsing throws checked exceptions. Always catch or declare ParserConfigurationException, SAXException, and IOException.

2. Forgetting to secure the parser factory

Default DocumentBuilderFactory is vulnerable to XXE. Always configure security features before parsing untrusted XML.

3. Using DOM for very large files

DOM loads the entire file into memory. For files over 50MB, use SAX or StAX to avoid OutOfMemoryError.

4. Not handling namespaces in XPath

In Java XPath, namespace-aware queries require a NamespaceContext. Without it, elements with namespaces won't match.

Practice Questions

  1. What is the main difference between SAX and StAX parsing? SAX is push-based (the parser pushes events to your handler). StAX is pull-based (your code pulls events from the parser).

  2. When should you choose DOM over SAX? Use DOM when you need random access to the document, need to modify the tree, or the XML is small enough to fit in memory.

  3. What does JAXB do? JAXB maps XML elements and attributes to Java object fields using annotations, enabling automatic serialization and deserialization.

Challenge: Write a Java program that reads an RSS feed XML using StAX, extracts the latest 10 items, and outputs them as a formatted HTML table with title, link, and publication date.

FAQ

What are the four ways to parse XML in Java?

DOM (tree-based), SAX (event-driven push), StAX (event-driven pull), and JAXB (object-binding).

Which Java XML parser is best for large files?

SAX or StAX, since they stream the XML without loading the full document into memory.

Is DOM parsing suitable for all XML files?

No. DOM loads the entire tree into memory, so it is unsuitable for files over 50-100MB.

How do I prevent XXE attacks in Java XML parsing?

Disable DTD processing and external entity resolution using the parser factory's setFeature methods.

What is JAXB?

Java Architecture for XML Binding — maps Java objects to XML and vice versa using annotations like @XmlRootElement and @XmlElement.

Can Java XML parsers handle namespaces?

Yes. DOM, SAX, StAX, and JAXB all support XML namespaces through namespace-aware parsing configuration.

Try It Yourself

Compile and run any of the examples above:

# Save any example as ParseXml.java
javac ParseXml.java
java ParseXml

# Expected output varies by example but follows
# the patterns shown in each code snippet above

For Maven projects, add no dependencies for DOM/SAX/StAX (they are in the JDK). For JAXB in Java 11+:

<dependency>
    <groupId>jakarta.xml.bind</groupId>
    <artifactId>jakarta.xml.bind-api</artifactId>
    <version>4.0.0</version>
</dependency>

What's Next

Tutorial What You'll Learn
XML Basics — Complete Guide Foundational XML concepts
XML Parsing in Python Parse XML with Python's ElementTree and lxml
XML Parsing in JavaScript Parse XML in browsers and Node.js

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro. Updated 2026-06-23.

What's Next

Congratulations on completing this XML Parsing in Java tutorial! Here's where to go from here:

  • Practice daily — Consistency is more important than long study sessions
  • Build a project — Create an XML configuration reader for a Java application
  • Explore related topics — Check out other XML tutorials in this category
  • Join the community — Discuss with other learners and share your progress

Remember: every expert was once a beginner. Keep coding!

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro