StAX Stream Reader
DomTrip can expose a Document tree as a StAX XMLStreamReader, enabling direct
integration with pull-based XML processing pipelines. This avoids the overhead of
serializing to a string and re-parsing when feeding domtrip documents into tools that
consume StAX events.
Note: Formatting preservation is intentionally lost at the StAX boundary since StAX events do not carry formatting metadata. The value is interoperability, not round-tripping through StAX.
When to Use StAX vs SAX
| StAX (pull) | SAX (push) | |
|---|---|---|
| Control flow | Caller drives with next() |
Parser drives via callbacks |
| Best for | Selective reading, filtering | Full-document processing |
| API style | Cursor / iterator | Event handler |
| DomTrip class | DomTripStreamReader |
SAXOutputter |
Both bridges are available; choose the one that matches your pipeline.
Basic Usage
Creating a StAX Reader
Document doc = Document.of(xml);
DomTripStreamReader reader = new DomTripStreamReader(doc);
while (reader.hasNext()) {
int event = reader.next();
switch (event) {
case XMLStreamConstants.START_ELEMENT:
System.out.println("Element: " + reader.getLocalName());
break;
case XMLStreamConstants.CHARACTERS:
System.out.println("Text: " + reader.getText());
break;
// ... handle other events
}
}
reader.close();
Using getElementText()
For elements that contain only text, use the convenience method:
reader.next(); // advance to START_ELEMENT
String text = reader.getElementText(); // reads text, leaves cursor at END_ELEMENT
Using nextTag()
Skip whitespace and comments to reach the next element boundary:
reader.next(); // advance to START_ELEMENT of parent
int event = reader.nextTag(); // skips whitespace/comments, returns START_ELEMENT or END_ELEMENT
JAXP Integration with StAXSource
The DomTripStAXSource class provides a StAXSource adapter for seamless use with
JAXP APIs like Transformer and Validator.
XSLT Transformation
Document doc = Document.of(xml);
StAXSource source = DomTripStAXSource.of(doc);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer(new StreamSource(xsltFile));
StringWriter writer = new StringWriter();
transformer.transform(source, new StreamResult(writer));
String result = writer.toString();
Building a DOM Tree
Document doc = Document.of(xml);
StAXSource source = DomTripStAXSource.of(doc);
DOMResult result = new DOMResult();
TransformerFactory.newInstance().newTransformer().transform(source, result);
org.w3c.dom.Document domDoc = (org.w3c.dom.Document) result.getNode();
StAX Events Emitted
The reader walks the domtrip tree and exposes the following StAX event types:
| domtrip Node | StAX Event Constant |
|---|---|
Document start |
START_DOCUMENT |
Document end |
END_DOCUMENT |
Element open |
START_ELEMENT |
Element close |
END_ELEMENT |
Text (regular) |
CHARACTERS |
Text (CDATA) |
CDATA |
Comment |
COMMENT |
ProcessingInstruction |
PROCESSING_INSTRUCTION |
Namespace Handling
Namespace declarations are separated from regular attributes and exposed via the
namespace accessor methods. The element's namespace URI is resolved and available
through getNamespaceURI().
// Given: <root xmlns="http://example.com" xmlns:ns="http://ns.example.com">
// <ns:child/>
// </root>
reader.next(); // START_ELEMENT "root"
reader.getNamespaceCount(); // 2
reader.getNamespacePrefix(0); // ""
reader.getNamespaceURI(0); // "http://example.com"
reader.getNamespacePrefix(1); // "ns"
reader.getNamespaceURI(1); // "http://ns.example.com"
reader.getNamespaceURI(); // "http://example.com" (element's own URI)
reader.next(); // START_ELEMENT "ns:child"
reader.getLocalName(); // "child"
reader.getPrefix(); // "ns"
reader.getNamespaceURI(); // "http://ns.example.com"
NamespaceContext
The reader provides a full javax.xml.namespace.NamespaceContext at any point
during traversal:
NamespaceContext ctx = reader.getNamespaceContext();
String uri = ctx.getNamespaceURI("ns"); // resolve prefix to URI
String prefix = ctx.getPrefix("http://ns.example.com"); // resolve URI to prefix
Attribute Access
Attributes (excluding namespace declarations) are accessible at START_ELEMENT events:
reader.next(); // START_ELEMENT
int count = reader.getAttributeCount();
for (int i = 0; i < count; i++) {
String name = reader.getAttributeLocalName(i);
String value = reader.getAttributeValue(i);
String ns = reader.getAttributeNamespace(i);
}
// Look up by namespace URI and local name
String value = reader.getAttributeValue("http://www.w3.org/2001/XMLSchema-instance", "type");
Document Properties
Document-level properties are available throughout the reader's lifecycle:
reader.getVersion(); // "1.0"
reader.getEncoding(); // "UTF-8"
reader.getCharacterEncodingScheme(); // "UTF-8"
reader.isStandalone(); // false
reader.standaloneSet(); // true if explicitly declared
Supported Properties
| Property Name | Value | Description |
|---|---|---|
javax.xml.stream.isValidating |
false |
No validation is performed |
javax.xml.stream.isNamespaceAware |
true |
Namespace-aware processing |
Classes
| Class | Purpose |
|---|---|
DomTripStreamReader |
XMLStreamReader backed by a domtrip Document |
DomTripStAXSource |
StAXSource adapter wrapping a domtrip Document |
All classes are in the eu.maveniverse.domtrip.stax package.
See Also
- SAX Event Output -- push-based SAX bridge for the same interoperability scenarios