尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

4种XML解析方式详解

4种XML解析方式详解
📅 发布时间:2026/6/21 9:30:22

详细讲解四种主流的XML解析方式,包括其原理、特点、适用场景和代码示例。

四种方式,可以分为两大类:

  1. 基于树的解析:将整个XML文档一次性加载到内存,形成一棵树形结构。
    • DOM
  2. 基于事件的解析:顺序读取XML文档,遇到节点时触发事件,边读边解析。
    • SAX
    • StAX
  3. 绑定类解析:通过映射关系,将XML节点直接绑定到程序中的对象。
    • JAXB

1. DOM - 文档对象模型 bG9pajNqLmNvbQ== loij3j.combG9pajNqLmNvbQ==

核心思想

一次性将整个XML文档读入内存,构建一个树形结构(Document对象)。程序可以通过操作这棵树上的节点(Node、Element、Attribute等)来随机访问和修改XML的任何部分。

工作流程

  1. 创建解析器工厂。
  2. 由工厂创建解析器。
  3. 解析器解析XML源(文件、输入流等),生成一个Document对象。
  4. 程序从Document对象开始,使用getElementsByTagName、getChildNodes等方法遍历和操作节点。

代码示例 (Java) bG9pajNqLmNvbQ== loij3j.combG9pajNqLmNvbQ==

假设有 books.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<bookstore><book id="1"><title>Java Programming</title><author>James Gosling</author><price>49.99</price></book><book id="2"><title>XML Guide</title><author>John Doe</author><price>39.95</price></book>
</bookstore>

使用DOM解析的Java代码:

import org.w3c.dom.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;public class DomParserExample {public static void main(String[] args) {try {// 1. 创建DocumentBuilderFactoryDocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();// 2. 创建DocumentBuilderDocumentBuilder builder = factory.newDocumentBuilder();// 3. 解析XML文件,获取Document对象Document document = builder.parse(new File("books.xml"));// 可选:规范化文档(合并相邻文本节点等)document.getDocumentElement().normalize();// 4. 获取所有book节点NodeList nodeList = document.getElementsByTagName("book");// 5. 遍历节点列表for (int i = 0; i < nodeList.getLength(); i++) {Node node = nodeList.item(i);if (node.getNodeType() == Node.ELEMENT_NODE) {Element element = (Element) node;// 获取属性String id = element.getAttribute("id");System.out.println("Book ID: " + id);// 获取子元素内容String title = element.getElementsByTagName("title").item(0).getTextContent();String author = element.getElementsByTagName("author").item(0).getTextContent();String price = element.getElementsByTagName("price").item(0).getTextContent();System.out.printf("Title: %s, Author: %s, Price: %s\n", title, author, price);System.out.println("---------------");}}} catch (Exception e) {e.printStackTrace();}}
}

优缺点 bG9pajNqLmNvbQ== loij3j.combG9pajNqLmNvbQ==

  • 优点:
    • 随机访问:可以方便地访问和修改任意节点。
    • 支持修改:可以轻松地对文档结构进行增删改查。
    • 易于编程:API直观,符合面向对象思想。
  • 缺点:
    • 内存消耗大:整个文档必须加载到内存中,不适合处理大型XML文件(如几个GB)。
    • 性能相对较低:解析和构建整个树结构需要时间。

适用场景 bG9pajNqLmNvbQ== loij3j.combG9pajNqLmNvbQ==

  • 需要随机访问XML文档的任意部分。
  • XML文档大小可控(通常小于几十MB)。
  • 需要对XML结构进行修改。

2. SAX - 简单API for XML

核心思想

基于事件驱动的推模型。解析器顺序读取XML文档,当遇到文档开始、元素开始、元素结束、文本内容等事件时,会调用程序中预先注册的回调方法。程序不持有整个文档的结构,只能被动地接收事件。

工作流程 bG9pajNqLmNvbQ== loij3j.combG9pajNqLmNvbQ==

  1. 创建SAXParserFactory和SAXParser。
  2. 创建一个继承自DefaultHandler的处理器。
  3. 重写处理器中的关键方法(如startElement, endElement, characters)。
  4. 解析器开始解析,在解析过程中自动调用处理器的相关方法。

代码示例 (Java) bG9pajNqLmNvbQ== loij3j.combG9pajNqLmNvbQ==

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;public class SaxParserExample {public static void main(String[] args) {try {// 1. 创建SAXParserFactory和SAXParserSAXParserFactory factory = SAXParserFactory.newInstance();SAXParser saxParser = factory.newSAXParser();// 2. 创建自定义的处理器BookHandler handler = new BookHandler();// 3. 开始解析saxParser.parse(new File("books.xml"), handler);} catch (Exception e) {e.printStackTrace();}}
}// 自定义事件处理器
class BookHandler extends DefaultHandler {private String currentValue;private String currentId;private boolean inBook = false;// 遇到元素开始时调用@Overridepublic void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {currentValue = ""; // 清空当前值if ("book".equals(qName)) {inBook = true;// 获取属性currentId = attributes.getValue("id");System.out.println("Book ID: " + currentId);}}// 遇到元素结束时调用@Overridepublic void endElement(String uri, String localName, String qName) throws SAXException {if (inBook) {switch (qName) {case "title":System.out.println("Title: " + currentValue);break;case "author":System.out.println("Author: " + currentValue);break;case "price":System.out.println("Price: " + currentValue);break;case "book":System.out.println("---------------");inBook = false;break;}}}// 处理元素内的文本内容@Overridepublic void characters(char[] ch, int start, int length) throws SAXException {// 累积文本内容(这个方法可能会被多次调用)currentValue += new String(ch, start, length).trim();}
}

优缺点 bG9pajNqLmNvbQ== loij3j.combG9pajNqLmNvbQ==

  • 优点:
    • 内存效率高:不需要将整个文档加载到内存,适合处理大型XML文件。
    • 速度快:因为是流式解析,延迟低。
  • 缺点:
    • 只读:无法修改XML文档。
    • 编程复杂:需要维护解析状态,逻辑相对复杂。
    • 随机访问能力差:无法直接跳转到某个特定节点。

适用场景 bG9pajNqLmNvbQ== loij3j.combG9pajNqLmNvbQ==

  • 只需要读取XML数据,不需要修改。
  • 处理非常大的XML文件。
  • 只需要XML中的部分数据,可以在找到所需数据后停止解析。

3. StAX - 用于XML的流API bG9pajNqLmNvbQ== loij3j.combG9pajNqLmNvbQ==

核心思想

基于迭代器的拉模型。程序可以主动地从解析器中“拉取”事件(如开始元素、结束元素),控制权在程序手中。它结合了SAX的高效和DOM的易用性。

工作流程 bG9pajNqLmNvbQ== loij3j.combG9pajNqLmNvbQ==

  1. 创建XMLInputFactory。
  2. 创建XMLEventReader(或XMLStreamReader)。
  3. 使用hasNext()和nextEvent()循环遍历解析事件。
  4. 根据事件的类型(START_ELEMENT, CHARACTERS, END_ELEMENT)进行相应处理。

代码示例 (Java) bG9pajNqLmNvbQ== loij3j.combG9pajNqLmNvbQ==

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.events.*;
import java.io.FileReader;public class StaxParserExample {public static void main(String[] args) {try {// 1. 创建XMLInputFactoryXMLInputFactory factory = XMLInputFactory.newInstance();// 2. 创建XMLEventReaderXMLEventReader eventReader = factory.createXMLEventReader(new FileReader("books.xml"));String currentId = null;String currentTag = null;// 3. 迭代处理事件while (eventReader.hasNext()) {XMLEvent event = eventReader.nextEvent();switch (event.getEventType()) {case XMLStreamConstants.START_ELEMENT:StartElement startElement = event.asStartElement();String qName = startElement.getName().getLocalPart();if ("book".equals(qName)) {// 获取属性Attribute idAttr = startElement.getAttributeByName(new javax.xml.namespace.QName("id"));if (idAttr != null) {currentId = idAttr.getValue();System.out.println("Book ID: " + currentId);}}currentTag = qName; // 记录当前标签名break;case XMLStreamConstants.CHARACTERS:Characters characters = event.asCharacters();String data = characters.getData().trim();if (data.length() > 0 && currentTag != null) {switch (currentTag) {case "title":System.out.println("Title: " + data);break;case "author":System.out.println("Author: " + data);break;case "price":System.out.println("Price: " + data);break;}}break;case XMLStreamConstants.END_ELEMENT:EndElement endElement = event.asEndElement();if ("book".equals(endElement.getName().getLocalPart())) {System.out.println("---------------");currentTag = null;}break;}}} catch (Exception e) {e.printStackTrace();}}
}

优缺点

  • 优点:
    • 内存效率高:与SAX一样是流式处理。
    • 控制灵活:拉模型让程序可以控制解析流程,更容易处理复杂逻辑。
    • 易于使用:相比SAX,API更直观,不需要复杂的回调。
  • 缺点:
    • 只读:标准StAX API是只读的(虽然有扩展可以支持写入)。

适用场景 bG9pajNqLmNvbQ== loij3j.combG9pajNqLmNvbQ==

  • 需要流式解析的高性能和高效率。
  • 希望比SAX更直观地控制解析过程。
  • 需要过滤XML文档,只处理感兴趣的部分。

4. JAXB - Java架构绑定 bG9pajNqLmNvbQ== loij3j.combG9pajNqLmNvbQ==

核心思想

通过注解将Java类与XML模式绑定。它可以将XML数据反序列化(Unmarshalling) 为Java对象,也可以将Java对象序列化(Marshalling) 为XML数据。这是一种最高级、最便捷的解析方式。

工作流程 bG9pajNqLmNvbQ== loij3j.combG9pajNqLmNvbQ==

  1. 创建带有JAXB注解的Java类(或通过XSD生成)。
  2. 创建JAXBContext。
  3. 使用Unmarshaller将XML转换为Java对象。
  4. 使用Marshaller将Java对象转换为XML。

代码示例 (Java) bG9pajNqLmNvbQ== loij3j.combG9pajNqLmNvbQ==

1. 创建带注解的Java类:

import javax.xml.bind.annotation.*;@XmlRootElement(name = "bookstore")
@XmlAccessorType(XmlAccessType.FIELD)
public class Bookstore {@XmlElement(name = "book")private List<Book> books = new ArrayList<>();// Getter and Setterpublic List<Book> getBooks() { return books; }public void setBooks(List<Book> books) { this.books = books; }
}@XmlAccessorType(XmlAccessType.FIELD)
public class Book {@XmlAttributeprivate String id;@XmlElementprivate String title;@XmlElementprivate String author;@XmlElementprivate double price;// Getters and Setterspublic String getId() { return id; }public void setId(String id) { this.id = id; }public String getTitle() { return title; }public void setTitle(String title) { this.title = title; }public String getAuthor() { return author; }public void setAuthor(String author) { this.author = author; }public double getPrice() { return price; }public void setPrice(double price) { this.price = price; }
}

2. 使用JAXB解析XML:

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.File;public class JaxbParserExample {public static void main(String[] args) {try {// 1. 创建JAXBContext(指定包含的类)JAXBContext context = JAXBContext.newInstance(Bookstore.class);// 2. 创建UnmarshallerUnmarshaller unmarshaller = context.createUnmarshaller();// 3. 将XML反序列化为Java对象Bookstore bookstore = (Bookstore) unmarshaller.unmarshal(new File("books.xml"));// 4. 像操作普通Java对象一样操作数据for (Book book : bookstore.getBooks()) {System.out.println("Book ID: " + book.getId());System.out.println("Title: " + book.getTitle());System.out.println("Author: " + book.getAuthor());System.out.println("Price: " + book.getPrice());System.out.println("---------------");}} catch (JAXBException e) {e.printStackTrace();}}
}

优缺点

  • 优点:
    • 开发效率极高:无需关心XML解析细节,直接操作对象。
    • 类型安全:在编译期就能发现类型错误。
    • 代码简洁:大大减少了样板代码。
  • 缺点:
    • 内存消耗:与DOM类似,需要将整个对象树加载到内存。
    • 需要预定义类:需要提前创建与XML结构对应的Java类。
    • 灵活性稍差:对于不规则或动态结构的XML处理起来比较麻烦。

适用场景 bG9pajNqLmNvbQ== loij3j.combG9pajNqLmNvbQ==

  • XML文档有固定的、已知的模式(XSD)。
  • 追求开发效率和代码可维护性。
  • 需要在Java对象和XML之间频繁转换。

总结对比 bG9pajNqLmNvbQ== loij3j.combG9pajNqLmNvbQ==

特性 DOM SAX StAX JAXB
解析模型 树形模型 事件驱动(推) 事件驱动(拉) 对象绑定
内存占用 高 低 低 高
速度 慢 快 快 中等
是否可写 是 否 是(扩展) 是
访问方式 随机访问 顺序只读 顺序只读 随机访问(对象)
编程复杂度 简单 复杂 中等 非常简单
适用场景 小文件、需修改 大文件、只读 大文件、需控制流程 已知模式、追求效率

选择建议: bG9pajNqLmNvbQ== loij3j.combG9pajNqLmNvbQ==

  • 小配置文件,且需修改:选 DOM
  • 读取超大XML日志文件:选 SAX 或 StAX(推荐StAX)
  • 已知XML结构,追求开发速度:选 JAXB
  • 需要灵活控制解析过程:选 StAX

相关新闻

  • 102302156 李子贤 数据采集第四次作业
  • 效果-Element 3D
  • 2025苏州餐饮公司测评:苏州会议餐配送选这些,全区域超省心

最新新闻

  • Rocky Linux 8 Python开发环境搭建全指南
  • 2026安徽普高线下考生,考不上普高能上全日制大学吗?合肥理工职教高考班11年升本榜首 - 小张zc
  • 2026无锡装修,老板直管工地+12小时响应,为什么这家公司转介绍率能达72%? - 装企自媒体训练营辉哥
  • Nintendo Switch游戏转储终极指南:NxDumpTool完整使用教程
  • Steam游戏自动破解终极指南:如何快速实现游戏自由启动
  • 深度解析Unity游戏逆向:Cpp2IL高级实战指南

日新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号