java中常用XML解析器的使用
(JAXP、DOM4J、Jsoup、JsoupXPath等常用XML解析器的使用)
XML概述
XML(Extensible Markup Language),可擴展標記語言。XML具有標簽自定義,語法嚴格,適用于存儲數(shù)據(jù)與傳輸數(shù)據(jù)等特點。
組成部分
1.文檔聲明
格式:<?xml 屬性列表 ?> 屬性列表: version:版本號,必須的屬性 encoding:編碼方式。告知解析引擎當前文檔使用的字符集,默認值:ISO-8859-1 standalone:是否獨立 yes:不依賴其他文件 no:依賴其他文件
2.指令
用于結(jié)合css:<?xml-stylesheet type="text/css" href="xml.css" rel="external nofollow" ?>
3.標簽
標簽名稱自定義,需遵循規(guī)則:
名稱可以包含字母、數(shù)字以及其他的字符 名稱不能以數(shù)字或者標點符號開始 名稱不能以字母 xml(或者 XML、Xml 等等)開始 名稱不能包含空格
4.屬性
id屬性值唯一
5.文本
CDATA區(qū):在該區(qū)域中的數(shù)據(jù)會被原樣展示 格式: <![CDATA[ 展示數(shù)據(jù)]]>
語法
xml文檔的后綴名 .xml xml第一行必須定義為文檔聲明,可選部分,如果存在需要放在文檔的第一行 xml文檔中有且僅有一個根標簽,是所有其他元素的父元素 屬性值必須使用引號(單雙都可)引起來 標簽必須正確關(guān)閉,所有的XML元素都必須有一個關(guān)閉標簽 xml標簽名稱區(qū)分大小寫
XML示例
<?xml version="1.0" encoding="UTF-8" ?> <students> <student id='1'> <name>小白</name> <age>20</age> </student> <student id='2'> <name>大白</name> <age>30</age> </student> </students>
約束
約束是規(guī)定xml文檔的書寫規(guī)則。約束分為:DTD(一種簡單的約束技術(shù))與Schema(一種復(fù)雜的約束技術(shù))共兩類。
DTD
students.dtd
<!ELEMENT students (student+) > <!ELEMENT student (name,age)> <!ELEMENT name (#PCDATA)> <!ELEMENT age (#PCDATA)> <!ATTLIST student name ID #REQUIRED>
引入方式:
內(nèi)部dtd:將約束規(guī)則定義在xml文檔中
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE students [ <!ELEMENT students (student+) > <!ELEMENT student (name,age)> <!ELEMENT name (#PCDATA)> <!ELEMENT age (#PCDATA)> <!ATTLIST student name ID #REQUIRED> ]> <students> <student name="xb"> <name>小白</name> <age>20</age> </student> <student name="db"> <name>大白</name> <age>30</age> </student> </students>
外部dtd:將約束的規(guī)則定義在外部的dtd文件中
本地:<!DOCTYPE 根標簽名 SYSTEM "dtd文件的位置">
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE students SYSTEM "student.dtd"> <students> <student name="xb"> <name>小白</name> <age>20</age> </student> <student name="db"> <name>大白</name> <age>30</age> </student> </students>
網(wǎng)絡(luò):<!DOCTYPE 根標簽名 PUBLIC "dtd文件名字" "dtd文件的位置URL">
Schema
1.填寫xml文檔的根元素 <?xml version="1.0" encoding="UTF-8"?> 2.引入xsi前綴 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3.引入xsd文件命名空間 xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" 4.為每一個xsd約束聲明一個前綴,作為標識 xmlns:mvc="http://www.springframework.org/schema/mvc"
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <bean></bean> <mvc:annotation-driven /> </beans>
XML的解析
解析就是操作xml文檔,將文檔中的數(shù)據(jù)讀取到內(nèi)存中,再將內(nèi)存中的數(shù)據(jù)保存到xml文檔中,持久化存儲。
解析方式
1. DOM:將標記語言文檔一次性加載進內(nèi)存,在內(nèi)存中形成一顆dom樹。操作方便,可以對文檔進行CRUD的操作,但占用內(nèi)存。 2. SAX:逐行讀取,基于事件驅(qū)動的,其優(yōu)點不占用內(nèi)容,但是只能讀取,不能增刪改。
常見解析器
1. JAXP:sun公司提供的解析器,支持dom和sax兩種思想 2. DOM4J:是一個十分優(yōu)秀的Java XML API,用來讀寫XML文件,具有性能優(yōu)異、功能強大和極其易使用的特點。 3. Jsoup:jsoup 是一款Java的HTML解析器,可直接解析某個URL地址、HTML文本內(nèi)容。它提供了一套非常省力的API,可通過DOM,CSS以及類似于jQuery的操作方法來取出和操作數(shù)據(jù)。 4. JsoupXPath:XPath即為XML路徑語言(XML Path Language),它是一種用來確定XML文檔中某部分位置的語言。
JAXP的使用
準備student.xml文件
創(chuàng)建student.xml文件,用于XML解析、寫入測試。
<?xml version="1.0" encoding="UTF-8" ?> <students> <student id='1'> <name>小白</name> <age>20</age> </student> <student id='2'> <name>大白</name> <age>30</age> </student> </students>
解析XML文檔
解析XML文檔的步驟:
使用javax.xml.parsers包下的DocumentBuilderFactory類中的newInstance()方法獲得一個解析器工廠對象 使用解析器工廠對象的newDocumentBuilder()方法獲得一個解析器對象 用解析器對象的parse(String uri)方法解析指定XML文檔并返回一個org.w3c.dom包下的Document對象 使用Document對象的getElementsByTagName(String tagname)方法獲得指定標簽名的NodeList列表 使用NodeList列表的item(int index)方法得到指定角標的節(jié)點對象 使用Node接口中的一系列方法對其進行操作
public static void main(String[] args) throws Exception { String path = ApplicationTests.class.getClassLoader().getResource("students.xml").getPath(); // 創(chuàng)建解析器工廠對象 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); // 創(chuàng)建解析器對象 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); // 解析指定XML文檔返回document Document document = documentBuilder.parse(new File(path)); // 獲得指定標簽名的NodeList列表 NodeList students = document.getElementsByTagName("name"); // 得到指定角標的節(jié)點對象 for (int i = 0; i < students.getLength(); i++) { Node node = students.item(i); // TODO 使用Node接口中的一系列方法對其進行操作 System.out.println("node name = " + node.getTextContent()); } }
寫入XML文檔
寫入XML文檔的步驟:
創(chuàng)建sex標簽節(jié)點 創(chuàng)建sex標簽對應(yīng)文本值 對sex標簽添加text 對某個節(jié)點添加sex標簽節(jié)點 通過javax.xml.transform包下的TransformerFactory.newInstance()方法得到一個回寫轉(zhuǎn)換器對象工廠 通過回寫轉(zhuǎn)換器對象工廠的newTransformer()方法得到回寫轉(zhuǎn)換器對象 使用回寫轉(zhuǎn)換器對象的transform(Source xmlSource, Result outputTarget)方法將內(nèi)存中內(nèi)容回寫入XML文檔。 Source參數(shù)通過new DOMSource(文檔對象)方法獲得 Result參數(shù)可以通過javax.xml.tramsform.stream包下的StreamResult(String URL)方法獲得
public static void main(String[] args) throws Exception { String path = ApplicationTests.class.getClassLoader().getResource("students.xml").getPath(); // 創(chuàng)建解析器工廠對象 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); // 創(chuàng)建解析器對象 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); // 解析指定XML文檔返回document Document document = documentBuilder.parse(new File(path)); //創(chuàng)建sex標簽 Node sex = document.createElement("sex"); //創(chuàng)建文本 Text text = document.createTextNode("男"); // sex標簽添加text sex.appendChild(text); Node node = document.getElementsByTagName("student").item(0); // student標簽添加sex節(jié)點 node.appendChild(sex); // 得到回寫轉(zhuǎn)換器對象工廠 TransformerFactory transformerFactory = TransformerFactory.newInstance(); // 得到回寫轉(zhuǎn)換器對象 Transformer transformer = transformerFactory.newTransformer(); // 將內(nèi)存中內(nèi)容回寫入XML文檔 transformer.transform(new DOMSource(document), new StreamResult(new File(path))); }
dom4j的使用
dom4j是一個開源的XML處理框架,集成了XPath,全面支持DOM、SAX、JAXP和Java平臺。是一個十分優(yōu)秀的Java XML API,用來讀寫XML文件,具有性能優(yōu)異、功能強大和極其易使用的特點。
GitHub地址:https://github.com/dom4j/dom4j
Document對象獲取方式
解析XML過程是通過獲取Document對象,然后繼續(xù)獲取各個節(jié)點以及屬性等操作,獲取Document對象是第一步,總共有三種方式。
1.使用DocumentHelper.createDocument()創(chuàng)建Document對象
Document document = DocumentHelper.createDocument(); //其中students是根節(jié)點,可以繼續(xù)添加其他節(jié)點等操作。 Element root = document.addElement("students");
2.建SAXReader對象然后轉(zhuǎn)換成Document對象
//創(chuàng)建SAXReader對象 SAXReader reader = new SAXReader(); //讀取文件 轉(zhuǎn)換成Document Document document = reader.read(new File("XXXX.xml"));
3.讀取XML文本內(nèi)容獲取Document對象
String xmlStr = "<students>......</students>"; Document document = DocumentHelper.parseText(xmlStr);
引入依賴
<!-- https://mvnrepository.com/artifact/org.dom4j/dom4j --> <dependency> <groupId>org.dom4j</groupId> <artifactId>dom4j</artifactId> <version>2.1.3</version> </dependency>
解析XML文檔
public static void main(String[] args) throws Exception { String path = XmlTest.class.getClassLoader().getResource("students.xml").getPath(); //UTF-8編碼 String filePath = URLDecoder.decode(path, "UTF-8"); //xml解析器 SAXReader saxReader = new SAXReader(); Document read = saxReader.read(filePath); //拿到根節(jié)點 Element rootElement = read.getRootElement(); //getNodes(rootElement); getALLNodes(rootElement); } static public void getNodes(Element rootElement) { System.out.println("節(jié)點名稱:" + rootElement.getName()); //拿到節(jié)點屬性 List<Attribute> attributes = rootElement.attributes(); for (Attribute attribute : attributes) { System.out.println("屬性:" + attribute.getName() + "---" + attribute.getText()); } //節(jié)點名稱 <name>大白</name>節(jié)點中的值 if (!rootElement.getTextTrim().equals("")) { System.out.println(rootElement.getName() + "---" + rootElement.getText()); } //迭代器遍歷 Iterator<Element> elementIterator = rootElement.elementIterator(); while (elementIterator.hasNext()) { //獲取當前節(jié)點值 Element next = elementIterator.next(); getNodes(next); } } static public void getALLNodes(Element rootElement) { System.out.println("根節(jié)點名稱:" + rootElement.getName()); //根節(jié)點下的節(jié)點 List<Element> elements = rootElement.elements(); for (Element element : elements) { //拿到節(jié)點屬性 List<Attribute> attributes = element.attributes(); for (Attribute attribute : attributes) { System.out.println("屬性:" + attribute.getName() + "---" + attribute.getText()); } //根節(jié)點下的節(jié)點的節(jié)點 List<Element> sonElements = element.elements(); for (Element sonElement : sonElements) { //節(jié)點名稱 <name>大白</name>節(jié)點中的值 if (!sonElement.getTextTrim().equals("")) { System.out.println(sonElement.getName() + "---" + sonElement.getText()); } } } }
文檔寫入XML
public static void main(String[] args) throws Exception { String path = ApplicationTests.class.getClassLoader().getResource("students.xml").getPath(); //UTF-8編碼 String filePath = URLDecoder.decode(path, "UTF-8"); //xml解析器 SAXReader saxReader = new SAXReader(); Document read = saxReader.read(filePath); createStudentNode(read, path); } /** * 創(chuàng)建新的student節(jié)點 * * @param document */ public static void createStudentNode(Document document, String path) { try (Writer writer = new OutputStreamWriter(new FileOutputStream(path), "UTF-8")) { // 獲取根節(jié)點 Element root = document.getRootElement(); // 添加根節(jié)點的子節(jié)點 新的student節(jié)點 Element b = root.addElement("student"); // 創(chuàng)建student節(jié)點的各個子節(jié)點 // 添加子節(jié)點的屬性 b.addAttribute("id", "3");//原有長度+1 // 添加子節(jié)點的的子節(jié)點name b.addElement("name").setText("createNode"); // 添加子節(jié)點的子節(jié)點age b.addElement("age").setText("22"); // 寫入XML document.write(writer); } catch (IOException e) { throw new RuntimeException(e); } }
Jsoup的使用
GitHub地址:https://github.com/jhy/jsoup
官網(wǎng):https://jsoup.org
jsoup 是一款Java 的HTML解析器,可直接解析某個URL地址、HTML文本內(nèi)容。它提供了一套非常省力的API,可通過DOM,CSS以及類似于jQuery的操作方法來取出和操作數(shù)據(jù)。
Jsoup主要功能
從一個URL,文件或字符串中解析HTML 使用DOM或CSS選擇器來查找、取出數(shù)據(jù) 可操作HTML元素、屬性、文本
引入依賴
<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup --> <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.13.1</version> </dependency>
核心對象
1.Jsoup
Jsoup是一個工具類,可以解析html或xml文檔,返回Document。
常用方法:
//解析xml或html字符串 public static Document parse(String html) { return Parser.parse(html, ""); } //解析xml或html文件 public static Document parse(File in, String charsetName) throws IOException { return DataUtil.load(in, charsetName, in.getAbsolutePath()); } //通過網(wǎng)絡(luò)路徑獲取指定的html或xml的文檔對象 public static Document parse(URL url, int timeoutMillis) throws IOException { Connection con = HttpConnection.connect(url); con.timeout(timeoutMillis); return con.get(); }
2.Document
Document是指文檔對象,代表內(nèi)存中的dom樹。
常用方法:
//根據(jù)id屬性值獲取唯一的element對象 public Element getElementById(String id) { Validate.notEmpty(id); Elements elements = Collector.collect(new Id(id), this); return elements.size() > 0 ? (Element)elements.get(0) : null; } //根據(jù)標簽名稱獲取元素對象集合 public Elements getElementsByTag(String tagName) { Validate.notEmpty(tagName); tagName = Normalizer.normalize(tagName); return Collector.collect(new org.jsoup.select.Evaluator.Tag(tagName), this); } //根據(jù)屬性名稱獲取元素對象集合 public Elements getElementsByAttribute(String key) { Validate.notEmpty(key); key = key.trim(); return Collector.collect(new Attribute(key), this); } //根據(jù)對應(yīng)的屬性名和屬性值獲取元素對象集合 public Elements getElementsByAttributeValue(String key, String value) { return Collector.collect(new AttributeWithValue(key, value), this); }
3.Elements與Element
Element是元素對象,Elements是元素Element對象的集合,可以當做 ArrayList<Element>使用。
常用方法:
//根據(jù)id屬性值獲取唯一的element對象 public Element getElementById(String id) { Validate.notEmpty(id); Elements elements = Collector.collect(new Id(id), this); return elements.size() > 0 ? (Element)elements.get(0) : null; } //根據(jù)class屬性值獲取elements對象集合 public Elements getElementsByClass(String className) { Validate.notEmpty(className); return Collector.collect(new Class(className), this); } //根據(jù)標簽名稱獲取元素對象集合 public Elements getElementsByTag(String tagName) { Validate.notEmpty(tagName); tagName = Normalizer.normalize(tagName); return Collector.collect(new org.jsoup.select.Evaluator.Tag(tagName), this); } //根據(jù)屬性名稱獲取元素對象集合 public Elements getElementsByAttribute(String key) { Validate.notEmpty(key); key = key.trim(); return Collector.collect(new Attribute(key), this); } //根據(jù)對應(yīng)的屬性名和屬性值獲取元素對象集合 public Elements getElementsByAttributeValue(String key, String value) { return Collector.collect(new AttributeWithValue(key, value), this); } //根據(jù)屬性名稱獲取屬性值 public String attr(String attributeKey) { Validate.notNull(attributeKey); if (!this.hasAttributes()) { return ""; } else { String val = this.attributes().getIgnoreCase(attributeKey); if (val.length() > 0) { return val; } else { return attributeKey.startsWith("abs:") ? this.absUrl(attributeKey.substring("abs:".length())) : ""; } } } //獲取文本內(nèi)容 public String text() { StringBuilder sb = new StringBuilder(); Element element; for(Iterator var2 = this.iterator(); var2.hasNext(); sb.append(element.text())) { element = (Element)var2.next(); if (sb.length() != 0) { sb.append(" "); } } return sb.toString(); } //獲取標簽體的所有內(nèi)容(包括字標簽的字符串內(nèi)容) public String html() { StringBuilder sb = new StringBuilder(); Element element; for(Iterator var2 = this.iterator(); var2.hasNext(); sb.append(element.html())) { element = (Element)var2.next(); if (sb.length() != 0) { sb.append("\n"); } } return sb.toString(); }
解析XML文檔
public static void main(String[] args) throws IOException { //根據(jù)xml文檔獲取,獲取Document對象 String path = JsoupDemo1.class.getClassLoader().getResource("student.xml").getPath(); //解析xml文檔,加載文檔進內(nèi)存 Document document = Jsoup.parse(new File(path), "utf-8"); //獲取元素對象Element Elements elements = document.getElementsByTag("name"); //循環(huán)得到每一個element對象 for (Element element : elements) { //獲取數(shù)據(jù) String name = element.text(); System.out.println(name); } //獲取屬性名為id的元素對象們 Elements elements1 = document.getElementsByAttribute("id"); System.out.println(elements1); //獲取id屬性值為2的元素對象 Elements elements2 = document.getElementsByAttributeValue("id", "2"); System.out.println(elements2); //獲取id屬性值的元素對象 Element elements3 = document.getElementById("2"); System.out.println(elements3); //通過Element對象獲取子標簽對象 Elements ele_name = elements3.getElementsByTag("name"); System.out.println(ele_name); //獲取student對象的屬性值 String id = elements3.attr("id"); System.out.println(id); //獲取文本內(nèi)容 String text = ele_name.text(); System.out.println(text); String html = ele_name.html(); System.out.println(html); }
JsoupXPath的使用
GitHub地址:https://github.com/zhegexiaohuozi/JsoupXpath
XPath即為XML路徑語言(XML Path Language),它是一種用來確定XML文檔中某部分位置的語言。
XPath基于XML的樹狀結(jié)構(gòu),提供在數(shù)據(jù)結(jié)構(gòu)樹中找尋節(jié)點的能力。
引入依賴
<!-- https://mvnrepository.com/artifact/cn.wanghaomiao/JsoupXpath --> <dependency> <groupId>cn.wanghaomiao</groupId> <artifactId>JsoupXpath</artifactId> <version>2.4.3</version> </dependency>
解析XML文檔
public static void main(String[] args) throws IOException, XpathSyntaxErrorException { //獲取student.xml的path String path = JsoupDemo6.class.getClassLoader().getResource("student.xml").getPath(); //獲取Document對象 Document document = Jsoup.parse(new File(path), "utf-8"); //根據(jù)document對象,創(chuàng)建JXDocument對象 JXDocument jxDocument = new JXDocument(document); //查詢所有student標簽 List<JXNode> jxNodes = jxDocument.selN("http://student"); for (JXNode jxNode : jxNodes) { System.out.println(jxNode); } //查詢所有student標簽下的name標簽 List<JXNode> jxNodes2 = jxDocument.selN("http://student/name"); for (JXNode jxNode : jxNodes2) { System.out.println(jxNode); } //查詢帶有id屬性的student標簽 List<JXNode> jxNodes3 = jxDocument.selN("http://student[@id]"); for (JXNode jxNode : jxNodes3) { System.out.println(jxNode); } //查詢帶有id屬性的student標簽并且id屬性值為1 List<JXNode> jxNodes4 = jxDocument.selN("http://student[@id='1']"); for (JXNode jxNode : jxNodes4) { System.out.println(jxNode); } }
到此這篇關(guān)于java中常用XML解析器的使用的文章就介紹到這了,更多相關(guān)java常用XML解析器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實現(xiàn)JDBC連接數(shù)據(jù)庫簡單案例
這篇文章主要介紹了Java實現(xiàn)JDBC連接數(shù)據(jù)庫簡單案例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08Java實戰(zhàn)之用hutool-db實現(xiàn)多數(shù)據(jù)源配置
在微服務(wù)搭建中經(jīng)常會使用到多數(shù)據(jù)庫情形這個時候,下面這篇文章主要給大家介紹了關(guān)于Java實戰(zhàn)之用hutool-db實現(xiàn)多數(shù)據(jù)源配置的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下2022-12-12Spring Boot2發(fā)布調(diào)用REST服務(wù)實現(xiàn)方法
這篇文章主要介紹了Spring Boot2發(fā)布調(diào)用REST服務(wù)實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-04-04servlet實現(xiàn)文件上傳、預(yù)覽、下載、刪除功能
這篇文章主要為大家詳細介紹了servlet實現(xiàn)文件上傳、預(yù)覽、下載、刪除功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09Java使用設(shè)計模式中的代理模式構(gòu)建項目的實例展示
這篇文章主要介紹了Java使用設(shè)計模式中的代理模式構(gòu)建項目的實例展示,代理模式中的代理對象可以在客戶端和目標對象之間起到中介的作用,需要的朋友可以參考下2016-05-05Spring Boot異步調(diào)用@Async過程詳解
這篇文章主要介紹了Spring Boot異步調(diào)用@Async過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-11-11Java基礎(chǔ)第二篇方法與數(shù)據(jù)成員
在上一篇文章中介紹了Java基礎(chǔ) 從HelloWorld到面向?qū)ο?,我們初步了解了對?object)。對象中的數(shù)據(jù)成員表示對象的狀態(tài)。對象可以執(zhí)行方法,表示特定的動作。這篇文章我們進一步深入到對象。了解Java中方法與數(shù)據(jù)成員的一些細節(jié)。2021-09-09