1. Introduction to streaming parsing
Historically, Java has two approaches to working with XML.
We already know that DOM (Document Object Model) builds the document tree in memory. It’s convenient to navigate elements and edit them, but for large files it’s too expensive: memory runs out quickly.
In turn, SAX (Simple API for XML) processes a file sequentially and fires events when it encounters tags. It’s memory-efficient and can handle huge documents. But writing handlers is inconvenient, and there’s no way to go back through the structure.
StAX (Streaming API for XML) emerged as a compromise. It’s also streaming like SAX, but it gives the programmer more control: we “pull” events from the stream ourselves when needed. This approach is called pull parsing, and it lets you write clearer, more flexible code.
Introduction to StAX
StAX (Streaming API for XML) is a modern streaming XML parser for Java, introduced in JDK 6+.
Main idea: pull parsing (“pull” parser).
Unlike SAX, where the parser calls your methods (push model), in StAX you control the process yourself:
You ask the parser: “Give me the next event!”
Analogy:
SAX is like television: events “flow” at you and you must react.
StAX is like a service where you click “next video” when you’re ready.
Key StAX classes
To work with StAX, you need two main classes from the javax.xml.stream package:
- XMLInputFactory — a factory for creating parsers.
- XMLStreamReader — the streaming parser that reads XML in chunks.
Basic code example:
import javax.xml.stream.*;
import java.io.FileInputStream;
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLStreamReader reader = factory.createXMLStreamReader(new FileInputStream("data.xml"));
while (reader.hasNext()) {
int event = reader.next();
// handle the event
}
reader.close();
2. How StAX works: the pull model
In StAX you control XML reading yourself:
- Open a stream (for example, a file).
- Create an XMLStreamReader.
- In a loop, call reader.next() to get the next event.
- Check the event type (START_ELEMENT, END_ELEMENT, CHARACTERS, etc.).
- When you reach the place you need, process the data.
- Close the parser.
Workflow diagram:
flowchart TD
A[Open XMLStreamReader] --> B{hasNext?}
B -- yes --> C["next()"]
C --> D{Event type?}
D -- START_ELEMENT --> E[Handle start of element]
D -- CHARACTERS --> F[Handle text]
D -- END_ELEMENT --> G[Handle end of element]
D -- END_DOCUMENT --> H[Finish]
B -- no --> H
Why is this convenient?
- You decide when to read the next element.
- You can “pause” where needed and process only part of the file.
- No need to write lots of handlers as in SAX.
3. Event types in StAX
When you call reader.next(), the parser returns an event type — an integer (a constant from the XMLStreamConstants interface). Here are the main event types:
- START_ELEMENT — start of an XML element (<tag>).
- END_ELEMENT — end of an XML element (</tag>).
- CHARACTERS — text content between tags.
- END_DOCUMENT — end of the document.
Example of handling events:
while (reader.hasNext()) {
int event = reader.next();
switch (event) {
case XMLStreamConstants.START_ELEMENT:
String name = reader.getLocalName();
System.out.println("Start element: " + name);
break;
case XMLStreamConstants.CHARACTERS:
String text = reader.getText().trim();
if (!text.isEmpty()) {
System.out.println("Text: " + text);
}
break;
case XMLStreamConstants.END_ELEMENT:
System.out.println("End element: " + reader.getLocalName());
break;
}
}
4. Useful details
When should you use StAX?
StAX is ideal if:
- The XML file is very large (gigabytes) and you don’t want to load it entirely into memory.
- You need to process only part of the document (for example, find a specific element and stop).
- You want simple, readable code: StAX is simpler than SAX and doesn’t require writing lots of handlers.
Example tasks:
- Import a large XML data file (for example, an export from 1C, bank statements, product catalogs).
- Search for and process only the elements you need (for example, only <transaction> out of a million records).
- Transform XML on the fly (for example, filtering, aggregation).
Comparison of DOM, SAX, and StAX
| Approach | Memory | Simplicity | Flexibility | When to use |
|---|---|---|---|---|
| DOM | High (everything in memory) | Very simple | Tree can be modified | Small/medium files when you need to edit XML |
| SAX | Minimal | Hard (event handlers) | Read-only, cannot go back | Very large files, simple processing |
| StAX | Minimal | Medium (pull model) | Can read in parts, easy to pause | Large files when you need flexibility and simplicity |
StAX is the sweet spot:
— Doesn’t consume as much memory as DOM.
— Doesn’t require complex handlers like SAX.
— Lets you control the parsing process.
5. Example: reading a large XML file with StAX
Suppose we have a file "books.xml":
<library>
<book>
<title>Java for Beginners</title>
<author>Ivan Ivanov</author>
</book>
<book>
<title>Advanced Java</title>
<author>Pyotr Petrov</author>
</book>
<!-- ... many books ... -->
</library>
Task: print all book titles.
StAX code:
import javax.xml.stream.*;
import java.io.*;
public class StaxDemo {
public static void main(String[] args) throws Exception {
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLStreamReader reader = factory.createXMLStreamReader(new FileInputStream("books.xml"));
while (reader.hasNext()) {
int event = reader.next();
if (event == XMLStreamConstants.START_ELEMENT && "title".equals(reader.getLocalName())) {
reader.next(); // move to CHARACTERS
System.out.println("Book: " + reader.getText());
}
}
reader.close();
}
}
Pros:
- We don’t load the entire file into memory.
- You can process even a million books — the program won’t crash.
6. Common mistakes when working with StAX
Error #1: forgot to close the parser or stream. Always close XMLStreamReader and the stream (InputStream) to avoid resource leaks.
Error #2: not checking the event type. Not all events are the start or end of an element. Check the event type, otherwise you can get empty strings or miss the data you need.
Error #3: ignoring element nesting. If the XML structure is complex (for example, books inside sections), track the current nesting level so you don’t confuse elements.
Error #4: using DOM for large files. If the file is large, don’t use DOM or you’ll get an OutOfMemoryError. For large files use StAX or SAX instead.
Error #5: not handling exceptions. Working with files and XML can throw exceptions (XMLStreamException, IOException). Handle them or rethrow as appropriate.
GO TO FULL VERSION