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.pswp.cn/bicheng/18576.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/18576.shtml
英文地址,請注明出處:http://en.pswp.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中的異常分為兩大類&…