Java的StAX解析器是一种基于流的XML处理API,它采用拉模式,由程序主动从解析器拉取事件或数据,相比DOM更省内存,相比SAX更易于控制流程。在实际项目中,使用StAX可以高效读取配置文件、接口报文等XML内容。
StAX的核心接口
StAX主要提供两套读取方式:基于事件的XMLEventReader和基于游标的XMLStreamReader。前者把每个节点封装成事件对象,后者通过游标直接访问当前节点信息。
使用XMLEventReader解析
下面示例展示如何用XMLEventReader读取一个简单的XML文件,并输出元素名称和文本内容。
import java.io.FileInputStream;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.events.XMLEvent;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.Characters;
public class StaxEventDemo {
public static void main(String[] args) throws Exception {
// 创建工厂实例
XMLInputFactory factory = XMLInputFactory.newInstance();
// 创建事件读取器
XMLEventReader reader = factory.createXMLEventReader(
new FileInputStream("data.xml"));
// 循环拉取事件
while (reader.hasNext()) {
XMLEvent event = reader.nextEvent();
if (event.isStartElement()) {
StartElement se = event.asStartElement();
System.out.println("开始标签: " + se.getName().getLocalPart());
} else if (event.isCharacters()) {
Characters ch = event.asCharacters();
if (!ch.isWhiteSpace()) {
System.out.println("文本: " + ch.getData());
}
}
}
reader.close();
}
}
使用XMLStreamReader解析
如果希望更少的对象创建开销,可以用XMLStreamReader,它以游标方式工作。
import java.io.FileInputStream;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamConstants;
public class StaxStreamDemo {
public static void main(String[] args) throws Exception {
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLStreamReader sr = factory.createXMLStreamReader(
new FileInputStream("data.xml"));
// 根据事件类型处理
while (sr.hasNext()) {
int type = sr.next();
if (type == XMLStreamConstants.START_ELEMENT) {
System.out.println("元素: " + sr.getLocalName());
} else if (type == XMLStreamConstants.CHARACTERS) {
String text = sr.getText().trim();
if (!text.isEmpty()) {
System.out.println("内容: " + text);
}
}
}
sr.close();
}
}
两种方式的对比
| 方式 | 特点 | 适用场景 |
|---|---|---|
| XMLEventReader | 事件对象化,代码清晰 | 结构复杂、需灵活处理 |
| XMLStreamReader | 游标访问,性能更好 | 大文件、高性能要求 |
写XML的简单示例
StAX也支持用XMLStreamWriter写XML,下面给出基础写法。
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamWriter;
public class StaxWriteDemo {
public static void main(String[] args) throws Exception {
XMLOutputFactory of = XMLOutputFactory.newInstance();
XMLStreamWriter w = of.createXMLStreamWriter(System.out);
w.writeStartDocument("UTF-8", "1.0");
w.writeStartElement("user");
w.writeAttribute("id", "1");
w.writeCharacters("张三");
w.writeEndElement();
w.writeEndDocument();
w.close();
}
}
注意事项
- 解析前建议设置XMLInputFactory的IS_COALESCING等属性,避免字符事件被拆分。
- 处理外部实体时注意关闭危险特性,防止XXE安全问题。
- 读取完成后务必调用close方法释放资源。
通过上述实践可以看出,Java的StAX解析器以流式拉模式提供了轻量且可控的XML处理能力,日常开发中可根据场景选择事件或游标API。