上一篇
如何使用Java解析XML
- 后端开发
- 2025-06-09
- 4459
在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的详细文档可在其官网查阅。