Java讀取xml文件的五種方式
前言
在編寫與 XML 數(shù)據(jù)交互的現(xiàn)代軟件應(yīng)用時,有效地讀取和解析 XML 文件是至關(guān)重要的。XML(可擴(kuò)展標(biāo)記語言)因其靈活性和自我描述性,已成為數(shù)據(jù)存儲和傳輸?shù)囊环N普遍格式。對于 Java 開發(fā)者來說,Java 提供了多種工具和庫來處理 XML 文件,每種工具都有其獨特的特點和最適用的場景。
本文旨在探討 Java 中處理 XML 文件的五種主要方法:DOM、SAX、StAX、JAXB 和 JDOM。這些技術(shù)各有優(yōu)勢和局限,選擇合適的方法可以大大提高開發(fā)效率和程序性能。我們將詳細(xì)介紹每種方法的工作原理、典型用途以及如何在 Java 程序中實現(xiàn)它們。
1、Java 讀取 xml 文件的五種方式
在 Java 中讀取 XML 文件有多種方法,這里列出五種常見的方式:
- DOM 解析器(Document Object Model):DOM 是處理 XML 文件的一種標(biāo)準(zhǔn)方法,它將整個 XML 文件加載到內(nèi)存中,然后構(gòu)造成一個樹狀結(jié)構(gòu)以便程序可以操作。這種方法適合于需要對文檔進(jìn)行頻繁讀寫操作的情況;
- SAX 解析器(Simple API for XML):SAX 是一種基于事件的解析方式,它不會將整個 XML 文檔加載到內(nèi)存中。這種方法適用于只需要讀取 XML 文檔的情況,特別是處理非常大的文件時;
- StAX 解析器(Streaming API for XML):StAX 是一種拉式解析(Pull Parsing)技術(shù),允許程序員按需讀取 XML 數(shù)據(jù)。這種方式適合于需要對 XML 文檔進(jìn)行增量處理的情況;
- JAXB(Java Architecture for XML Binding):JAXB 允許 Java 開發(fā)者通過注解將 Java 對象映射到 XML 文件,反之亦然。這適用于需要將 XML 數(shù)據(jù)直接轉(zhuǎn)換為 Java 對象的場合;
- JDOM(Java Document Object Model):JDOM 提供了一種簡潔而易用的 API,用于解析、創(chuàng)建和操作 XML 文檔。它基于樹形結(jié)構(gòu),類似于 DOM,但提供了更簡單的 API,適用于中小型 XML 文件的處理。
首先是 XML 示例:
xml 復(fù)制代碼 <?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 文檔加載到內(nèi)存中,以樹形結(jié)構(gòu)表示。這種方式易于遍歷和操作,適合對整個文檔進(jìn)行多次讀寫操作,但可能消耗大量內(nèi)存,不適合處理大型 XML 文件。
DOM 是 Java 標(biāo)準(zhǔn)庫的一部分,無需額外引入依賴。
代碼實現(xiàn):
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 { // 創(chuàng)建一個 DocumentBuilderFactory 實例,用于創(chuàng)建 DocumentBuilder DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 使用工廠創(chuàng)建一個 DocumentBuilder 實例,用于解析 XML 文檔 DocumentBuilder builder = factory.newDocumentBuilder(); // 使用 ClassLoader 獲取資源文件的輸入流,并解析成 Document 對象 Document document = builder.parse(DomReadExample.class.getClassLoader().getResourceAsStream("example.xml")); // 獲取 XML 文檔中所有名為 "book" 的元素節(jié)點 NodeList bookNodes = document.getElementsByTagName("book"); // 遍歷每個 "book" 元素節(jié)點,并輸出其子元素的內(nèi)容 for (int i = 0; i < bookNodes.getLength(); i++) { Node bookNode = bookNodes.item(i); Element bookElement = (Element) bookNode; // 獲取 "title"、"author" 和 "year" 子元素的內(nèi)容 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 以事件驅(qū)動的方式逐行解析 XML 文檔,并在解析過程中觸發(fā)事件。它不需要將整個文檔加載到內(nèi)存中,因此適用于處理大型 XML 文件,但相對于 DOM,它的操作稍顯復(fù)雜。
SAX 是 Java 標(biāo)準(zhǔn)庫的一部分,無需額外引入依賴。
代碼實現(xiàn):
package com.lizhengi; import org.xml.sax.*; import org.xml.sax.helpers.*; /** * SAX 解析 XML 示例 * 該類繼承了 DefaultHandler 類,用于處理 SAX 事件 * * @author liziheng */ public class SaxReadExample extends DefaultHandler { // 表示是否在書籍元素內(nèi)部 private boolean inBookElement = false; // 用于存儲當(dāng)前正在處理的元素的名稱 private String currentElement; // 當(dāng)前書籍的標(biāo)題 private String currentTitle; // 當(dāng)前書籍的作者 private String currentAuthor; // 當(dāng)前書籍的年份 private String currentYear; /** * 開始解析元素時調(diào)用 * * @param uri 元素的命名空間 URI * @param localName 元素的本地名稱 * @param qName 元素的限定名稱 * @param attributes 元素的屬性 */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) { if ("book".equals(qName)) { // 進(jìn)入書籍元素內(nèi)部 inBookElement = true; } // 存儲當(dāng)前元素的名稱 currentElement = qName; } /** * 處理元素字符數(shù)據(jù)時調(diào)用 * * @param ch 字符數(shù)組 * @param start 字符數(shù)據(jù)的起始索引 * @param length 字符數(shù)據(jù)的長度 */ @Override public 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)) { // 設(shè)置當(dāng)前書籍的標(biāo)題 currentTitle = content; } else if ("author".equals(currentElement)) { // 設(shè)置當(dāng)前書籍的作者 currentAuthor = content; } else if ("year".equals(currentElement)) { // 設(shè)置當(dāng)前書籍的年份 currentYear = content; } } } } /** * 結(jié)束解析元素時調(diào)用 * * @param uri 元素的命名空間 URI * @param localName 元素的本地名稱 * @param qName 元素的限定名稱 */ @Override public void endElement(String uri, String localName, String qName) { if ("book".equals(qName)) { // 打印當(dāng)前書籍的信息 System.out.println("Title: " + currentTitle + ", Author: " + currentAuthor + ", Year: " + currentYear); // 重置當(dāng)前書籍的信息 currentTitle = null; currentAuthor = null; currentYear = null; // 退出書籍元素內(nèi)部 inBookElement = false; } } /** * 主方法,程序入口 * * @param args 命令行參數(shù) * @throws Exception 拋出異常 */ public static void main(String[] args) throws Exception { // 創(chuàng)建 XML 解析器 XMLReader reader = XMLReaderFactory.createXMLReader(); // 設(shè)置內(nèi)容處理器為當(dāng)前類的實例 reader.setContentHandler(new SaxReadExample()); // 解析 XML 文件并觸發(fā) SAX 事件 reader.parse(new InputSource(SaxReadExample.class.getClassLoader().getResourceAsStream("example.xml"))); } }
4、StAX(流 API for XML)解析
StAX 提供了類似于 SAX 的事件驅(qū)動的解析方式,但與 SAX 不同,它提供了更簡潔的 API,并允許開發(fā)者在解析過程中靈活地控制流。這使得 StAX 更容易使用和理解。
引入依賴:
<dependency> <groupId>javax.xml.stream</groupId> <artifactId>stax-api</artifactId> <version>1.0-2</version> </dependency>
代碼實現(xiàn):
package com.lizhengi; import javax.xml.stream.*; /** * 使用 StAX(Streaming API for XML)方式讀取 XML 文件示例 * 該類實現(xiàn)了對 XML 文件的解析,并打印每本書的信息 * * @author lizhengi */ public class StaxReadExample { public static void main(String[] args) throws Exception { // 創(chuàng)建 XMLInputFactory 實例,用于創(chuàng)建 XMLStreamReader XMLInputFactory factory = XMLInputFactory.newInstance(); // 創(chuàng)建 XMLStreamReader 實例,用于逐行讀取 XML 文件內(nèi)容 XMLStreamReader reader = factory.createXMLStreamReader(StaxReadExample.class.getClassLoader().getResourceAsStream("example.xml")); // 用于存儲當(dāng)前正在處理的元素的名稱和內(nèi)容 String currentElement = null; String currentTitle = null; String currentAuthor = null; String currentYear = null; // 循環(huán)讀取 XML 文件中的內(nèi)容 while (reader.hasNext()) { int event = reader.next(); switch (event) { case XMLStreamConstants.START_ELEMENT: // 開始處理元素時,記錄當(dāng)前元素的名稱 currentElement = reader.getLocalName(); break; case XMLStreamConstants.CHARACTERS: // 處理元素的字符數(shù)據(jù)時,獲取字符數(shù)據(jù)的內(nèi)容 String content = reader.getText().trim(); if (!content.isEmpty()) { // 根據(jù)當(dāng)前元素的名稱,存儲相應(yīng)的內(nèi)容 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: // 結(jié)束處理元素時,檢查是否為書籍元素的結(jié)束標(biāo)簽 if ("book".equals(reader.getLocalName())) { // 打印當(dāng)前書籍的信息 System.out.println("Title: " + currentTitle + ", Author: " + currentAuthor + ", Year: " + currentYear); // 重置當(dāng)前書籍的信息,準(zhǔn)備處理下一本書 currentTitle = null; currentAuthor = null; currentYear = null; } break; } } } }
5、JAXB(Java Architecture for XML Binding)
JAXB 允許將 XML 數(shù)據(jù)綁定到 Java 對象,從而簡化了 XML 數(shù)據(jù)與 Java 對象之間的轉(zhuǎn)換過程。它通常用于處理 XML 數(shù)據(jù)的映射和序列化,而不是直接解析整個 XML 文檔。
JAXB 也是 Java 標(biāo)準(zhǔn)庫的一部分,無需額外引入依賴。
代碼實現(xiàn):
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 文件對應(yīng)的 Java 類,根元素為 "library" */ @XmlRootElement(name = "library") class Library { // 用于存儲書籍信息的列表,每個元素對應(yīng)一個書籍 @XmlElement(name = "book") public List<Book> books = new ArrayList<Book>(); } /** * 書籍信息的 Java 類 */ class Book { // 書籍標(biāo)題 @XmlElement public String title; // 書籍作者 @XmlElement public String author; // 出版年份 @XmlElement public int year; } /** * 使用 JAXB 方式讀取 XML 文件 * @author lizhengi */ public class JaxbReadExample { public static void main(String[] args) throws Exception { // 創(chuàng)建 JAXBContext 實例,用于創(chuàng)建 Unmarshaller JAXBContext context = JAXBContext.newInstance(Library.class); // 創(chuàng)建 Unmarshaller 實例,用于將 XML 數(shù)據(jù)轉(zhuǎn)換為 Java 對象 Unmarshaller unmarshaller = context.createUnmarshaller(); // 使用 Unmarshaller 解析 XML 文件,并將其轉(zhuǎn)換為 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,用于解析、創(chuàng)建和操作 XML 文檔。它基于樹形結(jié)構(gòu),類似于 DOM,但提供了更簡單的 API,適用于中小型 XML 文件的處理。
引入依賴:
<dependency> <groupId>org.jdom</groupId> <artifactId>jdom2</artifactId> <version>2.0.6.1</version> </dependency>
代碼實現(xiàn):
package com.lizhengi; import org.jdom2.*; import org.jdom2.input.*; /** * 使用 JDOM 方式讀取 XML 文件 * 該程序從 XML 文件中讀取圖書信息,并打印每本書的標(biāo)題、作者和年份 * XML 文件的根元素為 "library",每個 "book" 元素表示一本書 * @author lizhengi */ public class JdomReadExample { public static void main(String[] args) throws Exception { // 使用 SAXBuilder 創(chuàng)建解析器 SAXBuilder builder = new SAXBuilder(); // 使用解析器構(gòu)建 XML 文檔對象 Document document = builder.build(JdomReadExample.class.getClassLoader().getResourceAsStream("example.xml")); // 獲取 XML 文檔的根元素 Element root = document.getRootElement(); // 遍歷根元素下的所有 "book" 元素,并輸出每本書的信息 for (Element book : root.getChildren("book")) { // 獲取書籍的標(biāo)題、作者和年份 String title = book.getChildText("title"); String author = book.getChildText("author"); String year = book.getChildText("year"); // 打印輸出書籍信息 System.out.println("Title: " + title + ", Author: " + author + ", Year: " + year); } } }
以上就是Java讀取xml文件的五種方式的詳細(xì)內(nèi)容,更多關(guān)于Java讀取xml文件的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
myBatis實現(xiàn)三級嵌套復(fù)雜對象的賦值問題
這篇文章主要介紹了myBatis實現(xiàn)三級嵌套復(fù)雜對象的賦值問題,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11Java實現(xiàn)統(tǒng)計在線人數(shù)功能的方法詳解
很多人在筆試或者面試中問到:現(xiàn)在要你實現(xiàn)一個統(tǒng)計在線人數(shù)的功能,你該怎么設(shè)計?不知道的朋友,這篇文章就來告訴你具體實現(xiàn)方法2022-08-08Java的volatile和sychronized底層實現(xiàn)原理解析
文章詳細(xì)介紹了Java中的synchronized和volatile關(guān)鍵字的底層實現(xiàn)原理,包括字節(jié)碼層面、JVM層面的實現(xiàn)細(xì)節(jié),以及鎖的類型和MESI協(xié)議在多核處理器中的作用,文章還探討了synchronized和volatile的區(qū)別,以及如何通過Atomic類來實現(xiàn)更細(xì)粒度的原子操作,感興趣的朋友一起看看吧2025-03-03SharedWorkerGlobalScope屬性數(shù)據(jù)共享示例解析
這篇文章主要為大家介紹了SharedWorkerGlobalScope屬性數(shù)據(jù)共享示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12java理論基礎(chǔ)Stream?reduce實現(xiàn)集合元素歸約
這篇文章主要為大家介紹了java理論基礎(chǔ)Stream?reduce實現(xiàn)集合元素歸約示例詳解有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03MapStruct處理Java中實體與模型間不匹配屬性轉(zhuǎn)換的方法
今天小編就為大家分享一篇關(guān)于MapStruct處理Java中實體與模型間不匹配屬性轉(zhuǎn)換的方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03Spring中的@PropertySource注解源碼詳細(xì)解析
這篇文章主要介紹了Spring中的@PropertySource注解源碼詳細(xì)解析,@PropertySource注解,標(biāo)注在配置類@Configuration上面,下面主要分析一下@PropertySource注解的處理過程,也就是怎么把配置信息從.properies文件放到environment中的,需要的朋友可以參考下2024-01-01