XML 解析是将 XML 文档转换为应用程序可以处理的数据结构的过程。主要有两种解析方式:DOM(文档对象模型)和 SAX(简单 API for XML)。
DOM 解析
DOM 是一种基于树形结构的解析方式,它将整个 XML 文档加载到内存中,构建一个树形结构。
DOM 解析的特点
- 内存占用大:需要将整个文档加载到内存
- 随机访问:可以随机访问文档的任何部分
- 双向遍历:可以向前和向后遍历文档
- 修改能力:可以修改文档的结构和内容
- 适合小文档:适合处理较小的 XML 文档
DOM 解析示例(Java)
javaDocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(new File("data.xml")); // 获取根元素 Element root = document.getDocumentElement(); // 获取所有 book 元素 NodeList books = root.getElementsByTagName("book"); for (int i = 0; i < books.getLength(); i++) { Element book = (Element) books.item(i); String title = book.getElementsByTagName("title") .item(0) .getTextContent(); System.out.println("Title: " + title); }
SAX 解析
SAX 是一种基于事件的解析方式,它逐行读取 XML 文档,在遇到特定元素时触发事件。
SAX 解析的特点
- 内存占用小:不需要将整个文档加载到内存
- 顺序访问:只能顺序访问文档
- 单向遍历:只能向前遍历
- 只读模式:不能修改文档
- 适合大文档:适合处理大型 XML 文档
SAX 解析示例(Java)
javaSAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser saxParser = factory.newSAXParser(); DefaultHandler handler = new DefaultHandler() { boolean inTitle = false; public void startElement(String uri, String localName, String qName, Attributes attributes) { if (qName.equals("title")) { inTitle = true; } } public void characters(char[] ch, int start, int length) { if (inTitle) { System.out.println("Title: " + new String(ch, start, length)); } } public void endElement(String uri, String localName, String qName) { if (qName.equals("title")) { inTitle = false; } } }; saxParser.parse(new File("data.xml"), handler);
DOM 与 SAX 的对比
| 特性 | DOM | SAX |
|---|---|---|
| 内存占用 | 高 | 低 |
| 访问方式 | 随机访问 | 顺序访问 |
| 遍历方向 | 双向 | 单向 |
| 修改能力 | 可修改 | 只读 |
| 解析速度 | 较慢 | 较快 |
| 适用场景 | 小文档、需要修改 | 大文档、只读 |
其他解析方式
1. StAX(Streaming API for XML)
StAX 是一种拉式解析方式,结合了 DOM 和 SAX 的优点。
javaXMLInputFactory factory = XMLInputFactory.newInstance(); XMLStreamReader reader = factory.createXMLStreamReader(new FileInputStream("data.xml")); while (reader.hasNext()) { int event = reader.next(); if (event == XMLStreamConstants.START_ELEMENT && reader.getLocalName().equals("title")) { System.out.println("Title: " + reader.getElementText()); } }
2. JAXB(Java Architecture for XML Binding)
JAXB 提供了 XML 与 Java 对象之间的自动绑定。
javaJAXBContext context = JAXBContext.newInstance(Book.class); Unmarshaller unmarshaller = context.createUnmarshaller(); Book book = (Book) unmarshaller.unmarshal(new File("book.xml"));
选择解析方式的建议
- 选择 DOM:当需要随机访问、修改文档,且文档较小时
- 选择 SAX:当处理大型文档,且只需要顺序读取时
- 选择 StAX:当需要更好的性能和更灵活的控制时
- 选择 JAXB:当需要在 XML 和对象模型之间进行转换时
性能优化建议
- 使用合适的解析器:根据文档大小和需求选择合适的解析方式
- 启用验证:在开发时启用 Schema 验证,生产环境可关闭以提高性能
- 缓存解析结果:对于频繁访问的文档,缓存解析结果
- 使用流式处理:对于大型文档,使用 SAX 或 StAX 进行流式处理
XML 解析是处理 XML 数据的核心技术,选择合适的解析方式可以显著提高应用程序的性能和可维护性。