上一篇                     
               
			  如何使用Java解析XML
- 后端开发
- 2025-06-09
- 2624
 在Java中解析XML常用DOM、SAX或StAX API,也可使用JAXB实现对象绑定,DOM加载整个文档到内存树结构,SAX基于事件流逐行解析,StAX提供双向拉取解析,第三方库如JDOM/DOM4J简化操作,选择方式需考虑性能与内存需求。
 
DOM解析:适合小型XML文件
原理:将整个XML加载到内存形成树结构,支持随机访问。
优点:直观易用,可修改XML结构。
缺点:内存占用高,不适合大文件。 
import org.w3c.dom.*;
import javax.xml.parsers.*;
// 解析步骤
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("data.xml"); // 加载文件
// 获取根节点
Element root = doc.getDocumentElement();
System.out.println("根节点: " + root.getNodeName());
// 遍历子节点
NodeList nodeList = root.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
    Node node = nodeList.item(i);
    if (node.getNodeType() == Node.ELEMENT_NODE) {
        System.out.println("子节点: " + node.getNodeName());
    }
} 
SAX解析:高性能流处理
原理:基于事件驱动,逐行读取XML,不加载整个文件。
优点:内存占用低,适合大文件。
缺点:只读不可修改,需自定义事件处理器。 

import org.xml.sax.*;
import org.xml.sax.helpers.*;
// 自定义处理器
class MyHandler extends DefaultHandler {
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) {
        System.out.println("开始元素: " + qName);
    }
    @Override
    public void characters(char[] ch, int start, int length) {
        System.out.println("内容: " + new String(ch, start, length));
    }
}
// 使用SAX解析
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
saxParser.parse("data.xml", new MyHandler()); // 绑定处理器 
StAX解析:双向流处理
原理:基于拉模式(Pull Parsing),由程序控制读取进度。
优点:灵活高效,可同时读写。
缺点:API较复杂。 
import javax.xml.stream.*;
import java.io.*;
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
XMLStreamReader reader = inputFactory.createXMLStreamReader(new FileInputStream("data.xml"));
while (reader.hasNext()) {
    int eventType = reader.next();
    if (eventType == XMLStreamConstants.START_ELEMENT) {
        System.out.println("元素: " + reader.getLocalName());
    } else if (eventType == XMLStreamConstants.CHARACTERS) {
        System.out.println("内容: " + reader.getText());
    }
}
reader.close(); // 关闭资源 
JDOM解析:简化DOM操作
原理:封装DOM,提供更简洁的API。
优点:代码简洁,易上手。
缺点:需额外引入库(JDOM 2.x)。 

import org.jdom2.*;
import org.jdom2.input.SAXBuilder;
SAXBuilder saxBuilder = new SAXBuilder();
Document document = saxBuilder.build("data.xml"); // 构建文档
Element root = document.getRootElement();
// 获取子节点列表
List<Element> children = root.getChildren();
for (Element child : children) {
    System.out.println("节点: " + child.getName() + ", 值: " + child.getText());
} 
DOM4J解析:功能全面
原理:高性能开源库,支持XPath。
优点:API丰富,适合复杂操作。
缺点:需引入第三方依赖。 
import org.dom4j.*;
import org.dom4j.io.SAXReader;
SAXReader reader = new SAXReader();
Document document = reader.read("data.xml");
Element root = document.getRootElement();
// 使用XPath查找节点
List<Node> nodes = document.selectNodes("//book/title"); // 查找所有书名
for (Node node : nodes) {
    System.out.println("书名: " + node.getText());
} 
方案对比与选型建议
| 方法 | 内存占用 | 读写能力 | 适用场景 | 
|---|---|---|---|
| DOM | 高 | 读写 | 小型XML、需修改结构 | 
| SAX | 低 | 只读 | 大型文件、只读需求 | 
| StAX | 低 | 读写 | 流式处理、灵活控制 | 
| JDOM | 中 | 读写 | 快速开发、简洁API | 
| DOM4J | 中 | 读写 | 复杂查询、XPath支持 | 
选型指南:
- 优先考虑内存:大文件选SAX/StAX,小文件选DOM/JDOM/DOM4J。
- 优先考虑功能:需XPath选DOM4J,需简洁API选JDOM。
- 无依赖场景:Java标准库自带DOM/SAX/StAX。
最佳实践
- 关闭资源:使用try-with-resources确保流关闭:try (FileInputStream fis = new FileInputStream("data.xml")) { SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); parser.parse(fis, new MyHandler()); }
- 防御解析攻击:禁用外部实体防止XXE破绽: DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
- 性能优化:对大文件使用StAX并分批处理数据。
引用说明: 参考Oracle官方文档《Java API for XML Processing (JAXP)》及W3C XML解析标准,代码示例遵循Apache 2.0开源协议,第三方库JDOM、DOM4J的详细文档可在其官网查阅。

 
  
			