XML Tutorial · XML in Code · Lesson 19 of 28

XML in Java

Java's built-in XML APIs: DOM, SAX, StAX and the Transformer, plus secure parser settings and JAXB-style data binding.

Create a free account to save this page, take notes and track your progress. Sign in

The JAXP family

API Style Use for
DOM (DocumentBuilder) Whole tree in memory Small and medium documents you edit or query
SAX (SAXParser) Push: callbacks per event Large documents, read once
StAX (XMLStreamReader / Writer) Pull: you ask for the next event Large documents, simpler than SAX
XPath (javax.xml.xpath) Queries over a DOM Selecting nodes
Transformer (javax.xml.transform) XSLT 1.0, serialising Transforming and writing XML
Validation (javax.xml.validation) XSD 1.0 Checking documents

Jakarta XML Binding (JAXB, formerly built into Java 8) and Jackson XML map XML to Java objects with annotations; both are separate libraries today.

Java examples aren't runnable in the browser; the output shown is from a real JDK 21 run.

SAX: events as the parser reads

SAX handler
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;
import java.io.ByteArrayInputStream;

public class Main {
    public static void main(String[] args) throws Exception {
        String xml = """
                <shop>
                  <product sku="TEA-01" category="drinks"><name>Green tea</name><price>3.50</price><stock>40</stock></product>
                  <product sku="COF-02" category="drinks"><name>Coffee beans</name><price>9.90</price><stock>0</stock></product>
                  <product sku="MUG-07" category="kitchen"><name>Camel mug</name><price>12.00</price><stock>15</stock></product>
                  <product sku="PAN-03" category="kitchen"><name>Frying pan</name><price>29.00</price><stock>4</stock></product>
                </shop>""";
        var handler = new DefaultHandler() {
            String current = "";
            double total = 0;
            StringBuilder text = new StringBuilder();

            @Override public void startElement(String uri, String local, String qName, Attributes atts) {
                if (qName.equals("product")) current = atts.getValue("sku");
                text.setLength(0);
            }
            @Override public void characters(char[] ch, int start, int length) { text.append(ch, start, length); }
            @Override public void endElement(String uri, String local, String qName) {
                if (qName.equals("price")) {
                    total += Double.parseDouble(text.toString());
                    System.out.println(current + " costs " + text);
                }
            }
            @Override public void endDocument() { System.out.println("total: " + total); }
        };
        SAXParserFactory.newInstance().newSAXParser().parse(new ByteArrayInputStream(xml.getBytes("UTF-8")), handler);
    }
}

Output

TEA-01 costs 3.50
COF-02 costs 9.90
MUG-07 costs 12.00
PAN-03 costs 29.00
total: 54.4

Run this on your computer — see “Get Started” for setup.

StAX: pull parsing and writing

StAX reader and writer
import javax.xml.stream.*;
import java.io.*;

public class Main {
    public static void main(String[] args) throws Exception {
        String xml = """
                <shop>
                  <product sku="TEA-01" category="drinks"><name>Green tea</name><price>3.50</price><stock>40</stock></product>
                  <product sku="COF-02" category="drinks"><name>Coffee beans</name><price>9.90</price><stock>0</stock></product>
                  <product sku="MUG-07" category="kitchen"><name>Camel mug</name><price>12.00</price><stock>15</stock></product>
                  <product sku="PAN-03" category="kitchen"><name>Frying pan</name><price>29.00</price><stock>4</stock></product>
                </shop>""";
        XMLStreamReader r = XMLInputFactory.newInstance().createXMLStreamReader(new StringReader(xml));
        StringWriter out = new StringWriter();
        XMLStreamWriter w = XMLOutputFactory.newInstance().createXMLStreamWriter(out);
        w.writeStartElement("restock");
        String sku = null;
        while (r.hasNext()) {
            if (r.next() == XMLStreamConstants.START_ELEMENT) {
                if (r.getLocalName().equals("product")) sku = r.getAttributeValue(null, "sku");
                if (r.getLocalName().equals("stock") && Integer.parseInt(r.getElementText()) < 5) {
                    w.writeEmptyElement("item");
                    w.writeAttribute("sku", sku);
                }
            }
        }
        w.writeEndElement();
        w.close();
        System.out.println(out);
    }
}

Output

<restock><item sku="COF-02"/><item sku="PAN-03"/></restock>

Run this on your computer — see “Get Started” for setup.

Java's DocumentBuilderFactory resolves external entities by default. Always configure it securely for untrusted input; see XML security.

Test yourself

Which Java XML API lets your code ask for the next event, rather than receiving callbacks?

  1. StAX
  2. SAX
  3. DOM
  4. JAXB
Show answer

Answer: StAX

StAX is a pull parser; SAX pushes events to a handler.

Was this page helpful?