StAX是Java SE 6+内置的标准XML流式处理API,介于DOM与SAX之间,支持拉取式读取(XMLStreamReader)和流式写入(XMLStreamWriter),核心接口位于javax.xml.stream包,无需额外依赖。
StAX解析器到底是什么
StAX(Streaming API for XML)不是某种独立工具或第三方库,而是 Java SE 6+ 内置的、标准的 XML 流式处理 API。它介于 DOM(全量加载内存)和 SAX(纯事件驱动、只读)之间:既支持按需拉取(pull-style),又允许写入;既可控,又轻量。
核心接口是 XMLStreamReader(读)和 XMLStreamWriter(写),都定义在 javax.xml.stream 包里。JDK 自带实现(com.sun.xml.internal.stream.XMLInputFactoryImpl 等),无需额外依赖。
用 XMLStreamReader 逐个读取 XML 元素
与 SAX 不同,StAX 由你主动调用 next() 或 nextTag() 推进解析位置,逻辑更直观,也更容易中断、跳过或条件处理。
常见错误是忽略命名空间或属性顺序,导致 getAttributeValue(null, "id") 返回 null —— 实际上该属性可能在默认命名空间下,或名字拼错。
-
next()总是前进一位,返回当前事件类型(如START_ELEMENT、CHARACTERS) -
nextTag()跳过空白和注释,只停在 START_ELEMENT 或 END_ELEMENT - 获取属性推荐用
getAttributeValue(namespaceURI, localName),而非靠索引 - 文本内容必须在
CHARACTERS事件后调用getText(),且要检查是否为空白(isWhiteSpace())
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLStreamReader reader = factory.createXMLStreamReader(new FileInputStream("data.xml"));
while (reader.hasNext()) {
int event = reader.next();
if (event == XMLStreamConstants.START_ELEMENT) {
String name = reader.getLocalName();
if ("user".equals(name)) {
String id = reader.getAttributeValue(null, "id"); // 注意 null 表示无命名空间
System.out.println("Found user id=" + id);
}
} else if (event == XMLStreamConstants.CHARACTERS && !reader.isWhiteSpace()) {
System.out.println("Text: " + reader.getText());
}
}
reader.close();
用 XMLStreamWriter 写出格式化 XML
XMLStreamWriter 是“流式生成”的关键:不构建树,不缓存整段内容,边写边刷出。适合日志、导出、API 响应等场景。但默认不自动缩进,需手动控制换行和空格。