StAX是Java中拉模式XML解析API,适合大文件处理;通过XMLInputFactory创建XMLStreamReader,调用next()遍历节点,用getEventType()判断类型并提取数据,需手动close()释放资源并捕获XMLStreamException。

StAX(Streaming API for XML)是Java中处理XML的流式解析方式,适合大文件、内存敏感场景。它不像DOM那样全量加载进内存,也不像SAX那样纯事件驱动难以控制流程——StAX是“拉模式”(pull-based),由程序主动调用next()或nextTag()来读取节点,逻辑更直观、更易编写。
创建StAX解析器:XMLInputFactory
StAX解析从XMLInputFactory开始,它是工厂类,负责创建XMLEventReader(迭代式)或XMLStreamReader(游标式)。推荐用XMLStreamReader,因为它更轻量、方法更直接:
- 调用XMLInputFactory.newInstance().createXMLStreamReader(InputStream)获取读取器
- 确保输入流编码与XML声明一致(如UTF-8),否则可能抛XMLStreamException
- 可设置属性,例如factory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, false)关闭命名空间检查(默认开启)
遍历XML节点:用next()和getEventType()
XMLStreamReader通过游标逐个推进,每次调用next()返回当前事件类型,再用getXXX()方法提取内容:
- START_ELEMENT:用getLocalName()取标签名,getAttributeValue(null, "attr")取属性值
- CHARACTERS:用getTextTrim()安全获取文本内容(自动去首尾空白)
- END_ELEMENT:配合start标记做结构判断,比如匹配时结束一个对象构建
- 跳过注释、CDATA等非关键事件可用hasNext() + next()循环,或用nextTag()直接跳到下一个开始/结束标签
解析示例:读取图书列表
假设有如下XML片段:
立即学习“Java免费学习笔记(深入)”;
对应解析逻辑可写为:
- 遇到START_ELEMENT且getLocalName().equals("book")时,读取getAttributeValue(null, "id")
- 进入子元素后,根据getLocalName()区分title或author,在下一个CHARACTERS事件中取值
- 遇到END_ELEMENT且为book时,把临时Book对象加入列表
- 全程不用递归,用状态变量(如currentTag)或栈即可管理嵌套层级
释放资源与异常处理
StAX读取器不实现AutoCloseable(Java 8及以前),必须手动关闭:
- 在finally块中调用reader.close(),避免句柄泄漏
- 捕获XMLStreamException,注意其中包含行号和列号(getLocation().getLineNumber()),便于定位格式错误
- 若XML含外部DTD或DOCTYPE,可设factory.setProperty(XMLInputFactory.SUPPORT_DTD, false)禁用,防止XXE攻击










