Java 读取 xml 文件的五种方式

在编写与 XML 数据交互的现代软件应用时,有效地读取和解析 XML 文件是至关重要的。XML(可扩展标记语言)因其灵活性和自我描述性,已成为数据存储和传输的一种普遍格式。对于 Java 开发者来说,Java 提供了多种工具和库来处理 XML 文件,每种工具都有其独特的特点和最适用的场景。

本文旨在探讨 Java 中处理 XML 文件的五种主要方法:DOM、SAX、StAX、JAXB 和 JDOM。这些技术各有优势和局限,选择合适的方法可以大大提高开发效率和程序性能。我们将详细介绍每种方法的工作原理、典型用途以及如何在 Java 程序中实现它们。


文章目录

      • 1、Java 读取 xml 文件的五种方式
      • 2、DOM(文档对象模型)解析
      • 3、SAX(简单 API for XML)解析
      • 4、StAX(流 API for XML)解析
      • 5、JAXB(Java Architecture for XML Binding)
      • 6、JDOM(Java Document Object Model)


1、Java 读取 xml 文件的五种方式

在 Java 中读取 XML 文件有多种方法,这里列出五种常见的方式:

  • DOM 解析器(Document Object Model):DOM 是处理 XML 文件的一种标准方法,它将整个 XML 文件加载到内存中,然后构造成一个树状结构以便程序可以操作。这种方法适合于需要对文档进行频繁读写操作的情况;
  • SAX 解析器(Simple API for XML):SAX 是一种基于事件的解析方式,它不会将整个 XML 文档加载到内存中。这种方法适用于只需要读取 XML 文档的情况,特别是处理非常大的文件时;
  • StAX 解析器(Streaming API for XML):StAX 是一种拉式解析(Pull Parsing)技术,允许程序员按需读取 XML 数据。这种方式适合于需要对 XML 文档进行增量处理的情况;
  • JAXB(Java Architecture for XML Binding):JAXB 允许 Java 开发者通过注解将 Java 对象映射到 XML 文件,反之亦然。这适用于需要将 XML 数据直接转换为 Java 对象的场合;
  • JDOM(Java Document Object Model):JDOM 提供了一种简洁而易用的 API,用于解析、创建和操作 XML 文档。它基于树形结构,类似于 DOM,但提供了更简单的 API,适用于中小型 XML 文件的处理。

首先是 XML 示例:

xml
复制代码
<?xml version="1.0" encoding="UTF-8"?>
<library><book><title>Java Programming</title><author>John Smith</author><year>2022</year></book><book><title>Python Basics</title><author>Jane Doe</author><year>2021</year></book>
</library>

接下来,我们将使用不同的方式读取并打印这个 XML 示例。

2、DOM(文档对象模型)解析

DOM 将整个 XML 文档加载到内存中,以树形结构表示。这种方式易于遍历和操作,适合对整个文档进行多次读写操作,但可能消耗大量内存,不适合处理大型 XML 文件。

DOM 是 Java 标准库的一部分,无需额外引入依赖。

代码实现:

package com.lizhengi;import org.w3c.dom.*;
import javax.xml.parsers.*;/*** DOM 方式读取 XML文件* @author lizhengi*/
public class DomReadExample {public static void main(String[] args) throws Exception {// 创建一个 DocumentBuilderFactory 实例,用于创建 DocumentBuilderDocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();// 使用工厂创建一个 DocumentBuilder 实例,用于解析 XML 文档DocumentBuilder builder = factory.newDocumentBuilder();// 使用 ClassLoader 获取资源文件的输入流,并解析成 Document 对象Document document = builder.parse(DomReadExample.class.getClassLoader().getResourceAsStream("example.xml"));// 获取 XML 文档中所有名为 "book" 的元素节点NodeList bookNodes = document.getElementsByTagName("book");// 遍历每个 "book" 元素节点,并输出其子元素的内容for (int i = 0; i < bookNodes.getLength(); i++) {Node bookNode = bookNodes.item(i);Element bookElement = (Element) bookNode;// 获取 "title"、"author" 和 "year" 子元素的内容String title = bookElement.getElementsByTagName("title").item(0).getTextContent();String author = bookElement.getElementsByTagName("author").item(0).getTextContent();String year = bookElement.getElementsByTagName("year").item(0).getTextContent();// 打印输出图书的信息System.out.println("Title: " + title + ", Author: " + author + ", Year: " + year);}}
}

3、SAX(简单 API for XML)解析

SAX 以事件驱动的方式逐行解析 XML 文档,并在解析过程中触发事件。它不需要将整个文档加载到内存中,因此适用于处理大型 XML 文件,但相对于 DOM,它的操作稍显复杂。

SAX 是 Java 标准库的一部分,无需额外引入依赖。

代码实现:

package com.lizhengi;import org.xml.sax.*;
import org.xml.sax.helpers.*;/*** SAX 解析 XML 示例* 该类继承了 DefaultHandler 类,用于处理 SAX 事件** @author liziheng*/
public class SaxReadExample extends DefaultHandler {// 表示是否在书籍元素内部private boolean inBookElement = false;// 用于存储当前正在处理的元素的名称private String currentElement;// 当前书籍的标题private String currentTitle;// 当前书籍的作者private String currentAuthor;// 当前书籍的年份private String currentYear;/*** 开始解析元素时调用** @param uri         元素的命名空间 URI* @param localName   元素的本地名称* @param qName       元素的限定名称* @param attributes  元素的属性*/@Overridepublic void startElement(String uri, String localName, String qName, Attributes attributes) {if ("book".equals(qName)) {// 进入书籍元素内部inBookElement = true;}// 存储当前元素的名称currentElement = qName;}/*** 处理元素字符数据时调用** @param ch     字符数组* @param start  字符数据的起始索引* @param length 字符数据的长度*/@Overridepublic void characters(char[] ch, int start, int length) {if (inBookElement) {String content = new String(ch, start, length).trim();if (!content.isEmpty()) {if ("title".equals(currentElement)) {// 设置当前书籍的标题currentTitle = content;} else if ("author".equals(currentElement)) {// 设置当前书籍的作者currentAuthor = content;} else if ("year".equals(currentElement)) {// 设置当前书籍的年份currentYear = content;}}}}/*** 结束解析元素时调用** @param uri       元素的命名空间 URI* @param localName 元素的本地名称* @param qName     元素的限定名称*/@Overridepublic void endElement(String uri, String localName, String qName) {if ("book".equals(qName)) {// 打印当前书籍的信息System.out.println("Title: " + currentTitle + ", Author: " + currentAuthor + ", Year: " + currentYear);// 重置当前书籍的信息currentTitle = null;currentAuthor = null;currentYear = null;// 退出书籍元素内部inBookElement = false;}}/*** 主方法,程序入口** @param args 命令行参数* @throws Exception 抛出异常*/public static void main(String[] args) throws Exception {// 创建 XML 解析器XMLReader reader = XMLReaderFactory.createXMLReader();// 设置内容处理器为当前类的实例reader.setContentHandler(new SaxReadExample());// 解析 XML 文件并触发 SAX 事件reader.parse(new InputSource(SaxReadExample.class.getClassLoader().getResourceAsStream("example.xml")));}
}

4、StAX(流 API for XML)解析

StAX 提供了类似于 SAX 的事件驱动的解析方式,但与 SAX 不同,它提供了更简洁的 API,并允许开发者在解析过程中灵活地控制流。这使得 StAX 更容易使用和理解。

引入依赖:

        <dependency><groupId>javax.xml.stream</groupId><artifactId>stax-api</artifactId><version>1.0-2</version></dependency>

代码实现:

package com.lizhengi;import javax.xml.stream.*;/*** 使用 StAX(Streaming API for XML)方式读取 XML 文件示例* 该类实现了对 XML 文件的解析,并打印每本书的信息** @author lizhengi*/
public class StaxReadExample {public static void main(String[] args) throws Exception {// 创建 XMLInputFactory 实例,用于创建 XMLStreamReaderXMLInputFactory factory = XMLInputFactory.newInstance();// 创建 XMLStreamReader 实例,用于逐行读取 XML 文件内容XMLStreamReader reader = factory.createXMLStreamReader(StaxReadExample.class.getClassLoader().getResourceAsStream("example.xml"));// 用于存储当前正在处理的元素的名称和内容String currentElement = null;String currentTitle = null;String currentAuthor = null;String currentYear = null;// 循环读取 XML 文件中的内容while (reader.hasNext()) {int event = reader.next();switch (event) {case XMLStreamConstants.START_ELEMENT:// 开始处理元素时,记录当前元素的名称currentElement = reader.getLocalName();break;case XMLStreamConstants.CHARACTERS:// 处理元素的字符数据时,获取字符数据的内容String content = reader.getText().trim();if (!content.isEmpty()) {// 根据当前元素的名称,存储相应的内容if ("title".equals(currentElement)) {currentTitle = content;} else if ("author".equals(currentElement)) {currentAuthor = content;} else if ("year".equals(currentElement)) {currentYear = content;}}break;case XMLStreamConstants.END_ELEMENT:// 结束处理元素时,检查是否为书籍元素的结束标签if ("book".equals(reader.getLocalName())) {// 打印当前书籍的信息System.out.println("Title: " + currentTitle + ", Author: " + currentAuthor + ", Year: " + currentYear);// 重置当前书籍的信息,准备处理下一本书currentTitle = null;currentAuthor = null;currentYear = null;}break;}}}
}

5、JAXB(Java Architecture for XML Binding)

JAXB 允许将 XML 数据绑定到 Java 对象,从而简化了 XML 数据与 Java 对象之间的转换过程。它通常用于处理 XML 数据的映射和序列化,而不是直接解析整个 XML 文档。

JAXB 也是 Java 标准库的一部分,无需额外引入依赖。

代码实现:

package com.lizhengi;import javax.xml.bind.*;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.ArrayList;
import java.util.List;/*** XML 文件对应的 Java 类,根元素为 "library"*/
@XmlRootElement(name = "library")
class Library {// 用于存储书籍信息的列表,每个元素对应一个书籍@XmlElement(name = "book")public List<Book> books = new ArrayList<Book>();
}/*** 书籍信息的 Java 类*/
class Book {// 书籍标题@XmlElementpublic String title;// 书籍作者@XmlElementpublic String author;// 出版年份@XmlElementpublic int year;
}/*** 使用 JAXB 方式读取 XML 文件* @author lizhengi*/
public class JaxbReadExample {public static void main(String[] args) throws Exception {// 创建 JAXBContext 实例,用于创建 UnmarshallerJAXBContext context = JAXBContext.newInstance(Library.class);// 创建 Unmarshaller 实例,用于将 XML 数据转换为 Java 对象Unmarshaller unmarshaller = context.createUnmarshaller();// 使用 Unmarshaller 解析 XML 文件,并将其转换为 Library 对象Library library = (Library) unmarshaller.unmarshal(JaxbReadExample.class.getClassLoader().getResourceAsStream("example.xml"));// 遍历 Library 中的每本书,并打印其信息for (Book book : library.books) {System.out.println("Title: " + book.title + ", Author: " + book.author + ", Year: " + book.year);}}
}

6、JDOM(Java Document Object Model)

JDOM 提供了一种简洁而易用的 API,用于解析、创建和操作 XML 文档。它基于树形结构,类似于 DOM,但提供了更简单的 API,适用于中小型 XML 文件的处理。

引入依赖:

        <dependency><groupId>org.jdom</groupId><artifactId>jdom2</artifactId><version>2.0.6.1</version></dependency>

代码实现:

package com.lizhengi;import org.jdom2.*;
import org.jdom2.input.*;/*** 使用 JDOM 方式读取 XML 文件* 该程序从 XML 文件中读取图书信息,并打印每本书的标题、作者和年份* XML 文件的根元素为 "library",每个 "book" 元素表示一本书* @author lizhengi*/
public class JdomReadExample {public static void main(String[] args) throws Exception {// 使用 SAXBuilder 创建解析器SAXBuilder builder = new SAXBuilder();// 使用解析器构建 XML 文档对象Document document = builder.build(JdomReadExample.class.getClassLoader().getResourceAsStream("example.xml"));// 获取 XML 文档的根元素Element root = document.getRootElement();// 遍历根元素下的所有 "book" 元素,并输出每本书的信息for (Element book : root.getChildren("book")) {// 获取书籍的标题、作者和年份String title = book.getChildText("title");String author = book.getChildText("author");String year = book.getChildText("year");// 打印输出书籍信息System.out.println("Title: " + title + ", Author: " + author + ", Year: " + year);}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/18576.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库索引相关的知识点总结

目录 1. 索引的概念 2. 索引的作用 3. 索引的类型 4. 索引的缺点 5. 索引的使用场景 6. 索引的设计原则 7. 索引的实现技术 8. 索引的优化技巧&#xff1a; 数据库表的索引是一个非常重要的概念&#xff0c;它类似于一本书的目录&#xff0c;可以帮助我们快速找到所需的…

Idea工具的使用技巧与常见问题解决方案

一、使用技巧 1、启动微服务配置 如上图&#xff0c;在编辑配置选项&#xff0c;将对应的启动入口类加进去&#xff0c; 增加jvm启动参数&#xff0c; 比如&#xff1a; -Denvuat 或者 -Denvuat -Dfile.encodingUTF-8 启动配置可能不是-Denvuat&#xff0c;这个自己看代…

Android 11 Audio音频系统配置文件解析

在AudioPolicyService的启动过程中&#xff0c;会去创建AudioPolicyManager对象&#xff0c;进而去解析配置文件 //frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientIn…

MySQL目录和文件

MySQL目录和文件 bin目录 存储一些mysql脚本比如mysqld、mysqld-self等等&#xff0c;用于执行mysql一些操作 数据目录 show variables like datadir;--查看数据目录位置每一个数据库都有一个和数据库名相同的文件夹&#xff1b;MySQL5.7开始每创建一个表&#xff0c;在Innod…

Python机器学习 Tensorflow + keras 实现CNN

一、实验目的 1. 了解SkLearn Tensorlow使用方法 2. 了解SkLearn keras使用方法 二、实验工具&#xff1a; 1. SkLearn 三、实验内容 &#xff08;贴上源码及结果&#xff09; 使用Tensorflow对半环形数据集分 #encoding:utf-8import numpy as npfrom sklearn.datasets i…

Dynadot API调整一览

关于Dynadot Dynadot是通过ICANN认证的域名注册商&#xff0c;自2002年成立以来&#xff0c;服务于全球108个国家和地区的客户&#xff0c;为数以万计的客户提供简洁&#xff0c;优惠&#xff0c;安全的域名注册以及管理服务。 Dynadot平台操作教程索引&#xff08;包括域名邮…

AI Agent教育行业落地案例

【AI赋能教育】揭秘Duolingo背后的AI Agent&#xff0c;让学习更高效、更有趣&#xff01; ©作者|Blaze 来源|神州问学 引言 随着科技的迅猛发展&#xff0c;人工智能技术已经逐步渗透到我们生活的各个方面。而随着AI技术的广泛应用&#xff0c;教育培训正引领着一场新的…

149.二叉树:二叉树的前序遍历(力扣)

代码解决 这段代码实现了二叉树的前序遍历&#xff0c;前序遍历的顺序是&#xff1a;访问根节点 -> 递归遍历左子树 -> 递归遍历右子树。以下是详细解释&#xff0c;包括各个部分的注释&#xff1a; // 二叉树节点的定义 struct TreeNode {int val; // 节…

php -v在cmd中正常显示 在vscode中却报错

效果展示 原因 在vscode中 终端是 PowerShell PowerShell 默认情况下它不会继承系统的PATH环境变量 解决方案 使用CMD作为终端 打开VSCode设置&#xff08;File > Preferences > Settings 或 Ctrl,&#xff09;。搜索 terminal.integrated.shell.windows。更改其值…

springboot集成nacos

springboot集成nacos 1.版本2. POM依赖3. nacos服务3.1 下载nacos压缩包3.2 启动nacos 4. yaml配置5.Demo5.1 配置中心简单格式获取方式普通方式还可以再启动类上添加注解完成5.2 获取json格式的demo5.2 自动注册根据yaml配置 1.版本 nacos版本:2.3.2 springboot版本&#xff…

【已解决】使用StringUtils.hasLength参数输入空格仍然添加成功定价为负数仍然添加成功

Bug情景 今天在做功能测试时&#xff0c;发现使用使用StringUtils.hasLength&#xff08;&#xff09;方法以及定价为负数时&#xff0c;添加图书仍然成功 思考过程 0.1 当时在做参数检验时用了spring提供的StringUtils工具包&#xff0c;百度/大数据模型说&#xff1a; 0.2…

Redis:redis基础

Redis Remote Dictionary Service即远程字典服务 一个基于内存的key-value结构数据库,在开发中常常作为缓存存储不经常被改变的数据 基于内存存储,读写性能高 在企业中应用广泛 Redis介绍 用C语言开发的开源高性能键值对数据库,可以达到10w的qps,可以存储丰富的value类型…

【ubuntu20】--- 定时同步文件

在编程的艺术世界里&#xff0c;代码和灵感需要寻找到最佳的交融点&#xff0c;才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里&#xff0c;我们将共同追寻这种完美结合&#xff0c;为未来的世界留下属于我们的独特印记。 【Linux命令】--- 多核压缩命令大全&…

肉类食品解冻污水处理设备功能特点

诸城市鑫淼环保小编带大家了解一下肉类食品解冻污水处理设备功能特点 肉类食品解冻污水处理设备是专门用于处理肉类加工过程中产生的解冻废水的设备。这些设备在保障肉类食品生产过程中的卫生安全同时&#xff0c;也有效处理了废水&#xff0c;避免了环境污染。以下是对肉类食品…

VM虚拟机共享文件夹fuse: bad mount point `/mnt/hgfs‘: No such file or directory

报错显示挂载点 /mnt/hgfs 不存在&#xff0c;你需要先创建这个目录。可以按照以下步骤进行操作&#xff1a; 创建挂载点目录&#xff1a; sudo mkdir -p /mnt/hgfs 手动挂载共享文件夹&#xff1a; sudo vmhgfs-fuse .host:/ /mnt/hgfs -o allow_other 确保每次启动时自动…

液氮罐内部会污染吗

液氮罐是一种常见的存储液态氮的设备&#xff0c;广泛应用于科研、生物医药、食品冷冻等领域。但是&#xff0c;人们对于液氮罐内部是否会产生污染一直存在疑问。 我们来看液氮罐内部可能的污染源。液氮罐内部主要存在以下几种潜在的污染来源&#xff1a;气体污染、杂质污染、…

C++ | Leetcode C++题解之第117题填充每个节点的下一个右侧节点指针II

题目&#xff1a; 题解&#xff1a; class Solution { public:void handle(Node* &last, Node* &p, Node* &nextStart) {if (last) {last->next p;} if (!nextStart) {nextStart p;}last p;}Node* connect(Node* root) {if (!root) {return nullptr;}Node *…

推券客CMS淘宝优惠券网站源码

推券客CMS淘宝优惠券网站源码是一个以PHPMySQL进行开发的PHP淘宝客优惠券网站。支持电脑站、手机站以及微信公众号查券。支持多级代理返利和阿里妈妈最新的渠道管理等功能。 五大优势 一、全开源 推券客cms网站程序数据库完全开源,目前市场上基本都是以下2种淘宝客系统 第一…

LeetCode - 双指针(Two Pointers) 算法集合 [对撞指针、快慢指针、滑动窗口、双链遍历]

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/139270999 双指针算法是一种常见且灵活的技巧&#xff0c;通过使用两个指针协同完成任务。这些指针可以指向不同的元素&#xff0c;具体应用取决于…

Java中的异常处理策略:编写健壮的软件

异常处理是Java编程中一个重要的方面&#xff0c;正确的异常处理策略可以使软件更加健壮和易于维护。本文将详细探讨Java中的异常处理机制&#xff0c;介绍常见的异常类&#xff0c;以及提供有效的异常处理技巧和最佳实践。 #### 1. Java异常类别 Java中的异常分为两大类&…