Java StAX解析器怎么用 StAX流式处理XML教程

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片段:


  
    Effective Java
    Joshua Bloch
  

对应解析逻辑可写为:

  • 遇到START_ELEMENTgetLocalName().equals("book")时,读取getAttributeValue(null, "id")
  • 进入子元素后,根据getLocalName()区分titleauthor,在下一个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攻击