本文主要涉及:xml概念描述,xml的約束文件,dtd,xsd文件的定義使用,如何在xml中引用xsd文件,如何使用java解析xml,解析xml方式dom sax,dom4j解析xml文件css
SGML(SGM)標準通用標記語言html
是一種定義電子文檔結構和描述其內容的國際標準語言,具備極好的擴展性java
是全部電子文檔標記語言的起源,早在萬維網發明以前「通用標言」就已存在node
是1986年國際標準化組織出版發佈的一個信息管理方面的國際標準(ISO 8879:1986 信息處理)git
簡單的理解就是對於數據進行結構化組織呈現,用於描述文檔的顯示式樣或者描述文檔中文字的用途github
可擴展標記語言,是一種用於標記電子文件使其具備結構性的標記語言。web
與HTML同樣都是標準通用標記語言的子集,spring
只不過超文本標記語言被設計用來顯示數據數據庫
XML被設計用來傳輸和存儲數據.瀏覽器
語法上和HTML也是類似的,但HTML中的元素是固定的,而XML的標籤是能夠由用戶自定義的。
邏輯上來講SGML是很是適合用於Web項目中的
可是SGML的固有缺點,複雜/龐大/學習成本高等
因此XML這一SGML的子集,應運而生.
W3C在1998年2月發佈1.0版本
W3C在2004年2月發佈1.1版本,但由於1.1版本不能向下兼容1.0版本
因此如今使用的仍舊是1.0版本
W3school XML在線文檔
http://www.w3school.com.cn/xml/index.asp
W3C是萬維網聯盟(World Wide Web Consortium)英文的縮寫
它成立於1994年10月,以開放論壇的方式來促進開發互通技術(包括規格、指南、軟件和工具),開發網絡的所有潛能。
萬維網聯盟(W3C)從1994年成立以來,已發佈了90多份Web技術規範,領導着Web技術向前發展。
W3C認爲自身不是官方組織,所以將它正式發佈的規範稱爲推薦(建議)標準,意思是進一步標準化的建議,
可是因爲組織自身的權威性每每成爲事實上的標準。
XML在web中主要用途就是存儲數據,只要能方便的存儲數據,天然能夠交換數據.
程序的配置文件(這也是最後你們使用XML最多見的目的);
數據交換:不一樣語言之間用來交換數據,由於他是統一的格式
小型數據庫:用來當數據庫存儲數據。
HTML的元素都是固定的,而XML能夠自定義元素;
HTML用瀏覽器來解析執行, XML的解析器一般須要本身來寫(由於元素是自定義的);
HTML只能用來表示網頁,而XML能夠作的事情不少。
屬性文件只能存儲平面信息,而XML能夠存儲結構化信息;
解析屬性文件只須要使用Properties類就能夠了,而解析XML文檔是很複雜的。
XML是一種靈活的結構化數據存儲和傳輸格式,沒有預置的標籤(HTML就是預置的固定的,瀏覽器負責解析)
因此須要自定義標籤,
既然是自定義標籤 ,天然須要本身去動手解析
也就是說:
在Web項目中,想要使用XML做爲程序的一部分
1.語法格式 這個沒什麼好說的,必須遵照基本的XML規範
2.約束文件
任何的程序都不會是固定不變的,你的解析程序和XML文件也絕對不多是徹底不變的
好比可能你的XML文件須要用戶書寫,而後程序進行解析
若是用戶隨意書寫,不可能存在什麼程序可以保證徹底正確的解讀用戶的輸入
因此須要約束,也正是這個約束 讓XML的內容的書寫,和XML的解析程序達到了解耦的目的
只要引入了約束標準,XML文件的內容就不容許隨意書寫
只要遵循約束標準,解析程序就承諾必定能夠正確的解讀數據
3.解析 你本身定義的標籤,天然只有你本身才懂得每一個數據的含義
目前仍舊使用的是XML 1.0
一個基本的XML 形如:
<?xml version="1.0" encoding="ISO-8859-1"?> <note> <to>George</to> <from>John</from> <heading>Reminder</heading> <body>Don't forget the meeting!</body> </note>
XML是一個樹形結構,並且必須是一個樹形結構 必須有根元素
<bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price>30.00</price> </book> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> <book category="WEB"> <title lang="en">Learning XML</title> <author>Erik T. Ray</author> <year>2003</year> <price>39.95</price> </book> </bookstore>
文檔聲明
元素
屬性
註釋
CDATA區 、特殊字符
處理指令(PI:Processing Instruction)
在編寫XML文檔時,須要先使用文檔聲明來聲明XML文檔。且必須出如今文檔的第一行。
最簡單的語法:<?xml version=「1.0」?>
用encoding屬性說明文檔所使用的字符編碼。保存在磁盤上的文件編碼要與聲明的編碼一致。
如:<?xml version=「1.0」 encoding=「GB2312」?>
用standalone屬性說明文檔是否獨立,便是否依賴其餘文檔。
如:<?xml version=「1.0」 standalone=「yes」?>
沒有xml文檔聲明的xml文檔,不是格式良好的xml文檔
xml文檔聲明必須從xml文檔的1行1列開始 也就是必須第一行頂格寫
編碼屬性應當被指定爲文檔被保存時所使用的編碼
最好的避免錯誤的建議是:
使用支持編碼的編輯器
肯定編輯器使用的編碼
在您的 XML 文檔中使用相同的編碼屬性
XML中的每個標籤,就是一個元素
元素指的是從(且包括)開始標籤直到(且包括)結束標籤的部分
元素可包含其餘元素、文本或者二者的混合物。元素也能夠擁有屬性。
要求:
1.全部元素都必須有關閉標籤,省略關閉標籤是非法的。聲明不是XML的元素,因此第一行的聲明,並不須要關閉標籤
2.XML 標籤對大小寫敏感
3.XML 必須正確地嵌套
4.XML 文檔必須有且只有一個根元素
命名規則:
1.名稱能夠含字母、數字以及其餘的字符
2.名稱不能以數字或者標點符號開始
3.名稱不能以字符 「xml」(或者 XML、Xml)開始
4.名稱不能包含空格
5.可以使用任何名稱,沒有保留的字詞。
命名建議:
名稱應該具備描述性,而且在此基礎上儘量簡短,可使用下劃線 _
避免使用連字符 - ,好比 a-b 有些可能會僅僅解析到a
不要使用 英文句號 .
不要使用 英文冒號 : 會被當作命名空間解析
一個元素(標籤)能夠有多個屬性
XML的屬性是鍵值對的形式,
屬性由屬性名與屬性值構成,中間用等號鏈接 好比 sex="male"
他的屬性值必須加引號
單引號和雙引號都可使用
若是屬性值自己包含雙引號,那麼有必要使用單引號
究竟是使用元素仍是屬性?
建議是若是能夠,儘量的使用元素,而不是屬性
由於:
屬性沒法包含多重的值(元素能夠包含多個)
屬性沒法描述樹的結構(元素則是樹結構的一部分)
屬性不容易擴展
數據自己設置爲元素,數據的數據纔去設置爲屬性
註釋的語法與 HTML 的語法很類似:
<!-- 這是一個註釋 -->
註釋不能嵌套
全部 XML 文檔中的文本均會被解析器解析。
只有 CDATA 區段(CDATA section)中的文本會被解析器忽略。
CDATA 部分中的全部內容都會被解析器忽略。 CDATA 部分由 "<![CDATA[" 開始,由 "]]>" 結束
CDATA 部分不能包含字符串 "]]>"。也不容許嵌套的 CDATA 部分。
標記 CDATA 部分結尾的 "]]>" 不能包含空格或折行。
在 XML 中,文檔中的空格不會被刪除,都會保留
因此,在編寫XML文件時,使用換行和縮進等方式來讓原文件中的內容清晰可讀的「良好」書寫習慣在這個地方並非一件好事
XML 以 LF 存儲換行
特殊字符
在 XML 中,一些字符擁有特殊的意義。
若是你把字符 "<" 放在 XML 元素中,會發生錯誤,這是由於解析器會把它看成新元素的開始
預約義的實體
實體是用於定義引用普通文本或特殊字符的快捷方式的變量。
實體引用是對實體的引用。
實體可在內部或外部進行聲明。
&開頭 ; 結尾
處理指令,簡稱PI(Processing Instruction)。 瞭解一下
做用:用來指揮軟件如何解析XML文檔。
語法:必須以「<?」做爲開頭,以「?>」做爲結尾。與聲明是同樣
經常使用處理指令:
XML聲明:<?xml version=「1.0」 encoding=「GB2312」?>
xml-stylesheet指令:
做用:指示XML文檔所使用的CSS樣式XSL。
<?xml-stylesheet type="text/css" href="some.css"?>
注:對中文命名的標籤元素不起做用
驗證方式有兩種:
DTD
XML Schema
要理解限制自己的含義,限制是對於XML文檔結構的限制
XML中文檔的主要內容能夠說是 元素和屬性
限制也是針對元素和限制來進行的
大體也就是這些方面的限制
因此若是你想要給你的XML文檔編寫限制文件,你須要先肯定你本身的邏輯規則
也就是上面提到的這幾個主要問題
而後查找文檔 用對應的方法書寫出來便可
不一樣的限制方式天然有不一樣的語法,也就有不一樣的特色
XML Schema 比 DTD 更強大 是DTD的替代者
XML Schema 可針對將來的需求進行擴展
XML Schema 更完善,功能更強大
XML Schema 基於 XML 編寫
XML Schema 支持數據類型
XML Schema 支持命名空間
DTD w3c文檔
http://www.w3school.com.cn/dtd/dtd_intro.asp
XML Schema w3c文檔
http://www.w3school.com.cn/schema/schema_intro.asp
dtd xsd約束的引用
有三種方式
內部
外部(在本地)
公共(也是外部只不過不在本地)
內部直接定義在DOCUTYPE內,格式爲:
<!DOCUTYPE 根元素名稱[
]>
外部本地
<!DOCTYPE 根元素名稱 SYSTEM "dtd文檔路徑">
好比
<!DOCTYPE student SYSTEM "test.dtd">
公共DTD也就是網絡上的,本質也是外部
<!DOCTYPE 根元素 PUBLIC "DTD名稱" "DTD文檔的URL" >
好比 mybatis的mapper文件
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
通常都是使用第三方提供的技術框架等,使用XML進行數據配置,使用他們提供的DTD進行約束限制
XSD文檔中是建立元素和屬性的地方;
XML文檔中是使用元素和屬性的地方。
因此在XML文檔中須要說明使用了哪些XSD文檔。
在 XML 文檔中引用 Schema, 引用信息是設置到根元素的開始標籤內
<根元素名稱 此處爲引用信息
>
此處爲xml文件的正文內容
</根元素名稱>
想要弄清楚引用方式必須瞭解清楚xsd schema文檔的定義格式
每一個xsd文件都是一個XML文件
schema是全部文件的根元素
一個 schema 聲明每每看上去相似這樣
<?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3school.com.cn" xmlns="http://www.w3school.com.cn" elementFormDefault="qualified"> ... ... </xs:schema>
其中:
xmlns="http://www.w3school.com.cn" 表示默認的命名空間是"http://www.w3school.com.cn"
xmlns:xs="http://www.w3.org/2001/XMLSchema" 顯示 schema 中用到的元素和數據類型來自命名空間 "http://www.w3.org/2001/XMLSchema"。
同時它還規定了來自命名空間 "http://www.w3.org/2001/XMLSchema" 的元素和數據類型應該使用前綴 xs:
targetNamespace="http://www.w3school.com.cn" 表示被此 schema 定義的元素 來自命名空間: "http://www.w3school.com.cn"
elementFormDefault="qualified" 任何 XML 實例文檔所使用的且在此 schema 中聲明過的元素必須被命名空間限定
好比Spring的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
beans爲根元素,整個文檔的結構爲:
<beans>
</beans>
全部的引用信息設置在 開始標籤 <beans> 內
xmlns 與xmlns:xxx 是同樣的,只不過是xmlns是默認的命名空間,也就是省略了前綴的元素使用的命名空間
它的值也就是xsd文件中的targetNamespace 的值
還須要設置
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
一旦您擁有了可用的 XML Schema 實例命名空間
您就可使用 schemaLocation 屬性了。
此屬性有兩個值。第一個值是須要使用的命名空間。第二個值是供命名空間使用的 XML schema 的位置
須要引用xsd文檔的大體步驟
1,先確立你的根元素
好比:
<beans>
</beans>
2.而後選擇你的默認的命名空間
xmlns=""
3.默認的只有一個若是你還有更多,你須要設置別名
xmlns:xxx="" 能夠設置多個
可能還須要指定位置
4,須要給約束指定位置,指定位置的前提就是先包含XML Schema 實例命名空間:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5.使用xsi:schemaLocation="" 指定具體的位置
名稱空間是用來處理XML元素或屬性的名字衝突問題。你能夠理解爲Java中的包!包的做用就是用來處理類的名字衝突問題。
不管是在XML中,仍是在XSD中,都須要聲明名稱空間。這與Java中使用import來導包是一個道理。
若是被定義的元素在聲明時沒有指定目標名稱空間,那麼就是在無名稱空間中,
那麼咱們在使用這些在無名稱空間中的元素時,就不用再去聲明名稱空間了。
聲明名稱空間使用xmlns
例如:xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"。
這表示聲明瞭一個名稱空間,至關與Java中的import。
可是,Java中的import的含義是在下面使用的類,若是沒有給出包名,那麼就是import導入的這個類。
而xmlns表示,下面使用xsi爲前綴的元素或屬性,都是來自http://www.w3.org/2001/XMLSchema-instance名稱空間。
也就是說給名稱空間起了一個簡稱 別名 前綴 指定了就必須使用這個
例如在XSD文件中,xmlns:xsd="http://www.w3.org/2001/XMLSchema"就是聲明名稱空間,
而這個名稱空間是W3C的名稱空間,無需關聯文件就能夠直接聲明!
在XSD文件中全部使用xsd爲前面的元素和屬性都是來自http://www.w3.org/2001/XMLSchema名稱空間。
名稱空間命名:通常名稱空間都是以公司的URL來命名,即網址!固然也能夠給名稱空間命名爲aa、bb之類的名字,但這可能會致使名稱空間的重名問題。
前綴命名:前綴的命名沒有什麼要求,但通常對http://www.w3.org/2001/XMLSchema名稱空間的前綴都是使用xs或xsd。
http://www.w3.org/2001/XMLSchema-instance的前綴使用xsi。
所謂默認名稱空間就是在聲明名稱空間時,不指定前綴,也能夠理解爲前綴爲空字符串的意思。
這樣定義元素時,若是沒有指定前綴的元素都是在使用默認名稱空間中的元素。
xmlns=」http://www.w3.org」
當在文檔中使用<xxx>時,那麼<xxx>元素就是http://www.w3.org名稱空間中聲明的元素。
注意:沒有指定前綴的屬性不表示在默認名稱空間中,而是表示沒有名稱空間。也就是說,默認名稱空間不會涉及到屬性,只對元素有效!
DOM:Document Object Model,文檔對象模型。這種方式是W3C推薦的處理XML的一種方式。
SAX:Simple API for XML。這種方式不是官方標準,屬於開源社區XML-DEV,屬於事實上的標準
這是兩種操做邏輯,是一種規範描述,是一組標準接口
這並非針對java語言解析dom的技術
DOM和SAX只是定義了一些接口,以及某些接口的缺省實現,而這個缺省實現只是用空方法來實現接口。
一個應用程序若是須要DOM或SAX來訪問XML文檔,還須要一個實現了DOM或SAX的解析器,
也就是說這個解析器須要實現DOM或SAX中定義的接口以可以提供DOM或SAX中定義的功能。
DOM要求解析器把整個XML文檔裝載到一個Document對象中。
Document對象包含文檔元素,即根元素,根元素包含N多個子元素…
一個XML文檔解析後對應一個Document對象,
這說明使用DOM解析XML文檔方便使用,由於元素與元素之間還保存着結構關係。
優先:使用DOM,XML文檔的結構在內存中依然清晰。元素與元素之間的關係保留了下來!
缺點:若是XML文檔過大,那麼把整個XML文檔裝載進內存,可能會出現內存溢出的現象!
DOM會一行一行的讀取XML文檔,最終會把XML文檔全部數據存放到Document對象中。
SAX也是一行一行的讀取XML文檔,可是當XML文檔讀取結束後,SAX不會保存任何數據,同時整個解析XML文檔的工做也就結束了。
可是,SAX在讀取一行XML文檔數據後,就會給感興趣的用戶一個通知!這是一種回調的形式
例如當SAX讀取到一個元素的開始時,會通知用戶當前解析到一個元素的開始標籤。
而用戶能夠在整個解析的過程當中完成本身的業務邏輯,當SAX解析結束,不會保存任何XML文檔的數據。
優先:使用SAX,不會佔用大量內存來保存XML文檔數據,效率也高。
缺點:當解析到一個元素時,上一個元素的信息已經丟棄,也就是說沒有保存元素與元素之間的結構關係,這也大大限制了SAX的使用範圍。
若是隻是想查詢XML文檔中的數據,那麼使用SAX是最佳選擇!
JAXP(Java API for XMLProcessing,意爲XML處理的Java API)是Java XML程序設計的應用程序接口之一
JAXP是sun提供的 用於隱藏底層解析器的實現
java要求XML解析器去實現JAXP提供的接口,這樣可讓用戶使用解析器時不依賴特定的XML解析器
JAXP自己不是解析器
也不是解析方式(DOM或SAX),它只是讓用戶在使用DOM或SAX解析器時不依賴特色的解析器。
因此能夠說是JAXP是java提供的統一的解析XML的接口規範
你不在須要關注任何的具體的XML解析器的細節
只須要使用JAXP接口規範定義的API便可
jdk中 javax.xml.parsers包下,四個類:
其中DOM方式:
DocumentBuilder 解析器類
DocumentBuilderFactory 解析器工廠
DocumentBuilder 抽象類,可使用DocumentBuilderFactory.newDocumentBuilder() 得到
DocumentBuilderFactory 抽象類,可使用他的newInstance()方法獲取實例
parse方法返回Document接口,父接口是Node
示例:
1 import javax.xml.parsers.DocumentBuilder; 2 import javax.xml.parsers.DocumentBuilderFactory; 3 import javax.xml.transform.Transformer; 4 import javax.xml.transform.TransformerFactory; 5 import javax.xml.transform.dom.DOMSource; 6 import javax.xml.transform.stream.StreamResult; 7 8 import org.w3c.dom.Document; 9 import org.w3c.dom.Element; 10 import org.w3c.dom.Node; 11 import org.w3c.dom.NodeList; 12 import org.w3c.dom.Text; 13 14 public class DomParseTest { 15 16 public static void main(String[] args) throws Exception { 17 18 19 20 //建立解析器工廠 21 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); 22 //使用工廠建立解析器 23 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); 24 //使用解析器解析XML文件獲得Document對象 25 Document document = documentBuilder.parse("src/dom/test.xml"); 26 //根據標籤名獲取 NodeList是一個集合 集合中的元素時Node 使用item() 獲取元素 27 NodeList nodeList = document.getElementsByTagName("name"); 28 for(int i=0;i<nodeList.getLength();i++) { 29 Node node = nodeList.item(i); 30 //獲得標籤裏面的內容 31 System.out.println(node.getTextContent()); 32 } 33 34 //給第一個學生增長一個性別屬性 35 //查找第一個學生 36 Node firstStudent = document.getElementsByTagName("student").item(0); 37 //建立性別標籤 38 Element sexElement = document.createElement("sex"); 39 //建立性別標籤對應的文本 40 Text sexElementText= document.createTextNode("男"); 41 //文本添加到標籤上 42 sexElement.appendChild(sexElementText); 43 //標籤添加到第一個學生節點上 44 firstStudent.appendChild(sexElement); 45 46 //回寫數據 47 //須要使用transformer 抽象類 由工廠建立,工廠也是抽象類由newInstance()方法建立 48 TransformerFactory transformerFactory = TransformerFactory.newInstance(); 49 Transformer transformer = transformerFactory.newTransformer(); 50 //擁有tranform()方法進行傳輸數據 51 //transform(Source xmlSource, Result outputTarget) 52 //Source的實現類DOMSource有構造方法 53 //Result接口有實現類StreamResult 54 transformer.transform(new DOMSource(document), new StreamResult("src/dom/test.xml")); 55 56 57 } 58 59 }
<?xml version="1.0" encoding="UTF-8" standalone="no"?><students>
<student>
<name>張三</name>
<age>18</age>
</student>
<student>
<name>李四</name>
<age>28</age>
</student>
</students>
雖然方法有不少,可是本質很簡單,解析器,解析器工廠
解析器解析出來文檔結構
既然是DOM樹,天然都是節點
Document Element Text Attr 也都是節點 Node 類型的
NodeList 是包含Node 的集合 可使用item方法獲取節點 因此說一旦解析出來文檔
一切皆是Node 針對於操做方法都在這個體系內了
再詳細一點的說就是:
不管使用什麼DOM解析器,最終用戶都須要獲取到Document對象,一個Document對象對應整個XML文檔。也能夠這樣說,Document對象就是XML文檔在內存中的表示形式。
在DOM中提供了不少接口,用來描述XML文檔中的組成部分。
其中包括:文檔(Document)、元素(Element)、屬性(Attr)、文本(Text)、註釋(Comment)、CDATA段(CDATASection)等等。
不管是哪一種XML文檔組成部分,都是節點(Node)的子接口。
l String getNodeName():獲取當前節點的名字。若是當前節點是Element,那麼返回元素名稱。若是當前節點是Text那麼返回#text。若是當前節點是Document那麼返回#document;
l String getNodeValue():獲取當前節點的值。只有文本節點有值,其它節點的值都爲null;
l String getTextContext():獲取當前節點的文本字符串。若是當前節點爲Text,那麼獲取節點內容。若是當前節點爲Element,那麼獲取元素中全部Text子節點的內容。例如當前節點爲:<name>zhangSan</name>,那麼本方法返回zhangSan。若是當前節點爲:<student><name>zhangSan</name><age>23</age><sex>male</sex></student>,那麼本方法返回zhangSan23male。
l short getNodeType():獲取當前節點的類型。Node中有不少short類型的常量,能夠經過與這些常量的比較來判斷當前節點的類型。if(node.getNodeType() == Node.ELEMENT_NODE);
Node獲取子節點和父節點方法,只有Document和Element才能使用這些方法:
l NodeList getChildNodes():獲取當前節點的全部子節點。NodeList表示節點列表,它有兩個方法:
l int getLength():獲取集合長度;
l Node item(int index):獲取指定下標的節點。
l Node getFirstNode():獲取當前節點的第一個子節點;
l Node getLastNode():獲取當前節點的最後一個子節點;
l Node getParentNode():獲取當前節點的父節點。注意Document的父節點爲null。
Node獲取弟兄節點的方法,只有Element才能使用這些方法:
l Node getNextSibling():獲取當前節點的下一個兄弟節點;
l Node getPreviousSibling():獲取當前節點的上一個兄弟節點。
Node添加、替換、刪除子節點方法:
l Node appendChild(Node newChild):把參數節點newChild添加到當前節點的子節點列表的末尾處。返回值爲被添加的子節點newChild對象,方便使用鏈式操做。若是newChild在添加以前已經在文檔中存在,那麼就是修改節點的位置了;
l Node insertBefore(Node newChild, Node refNode):把參數節點newChild添加到當前節點的子節點refNode以前。返回值爲被添加的子節點newChild對象,方便使用鏈式操做。若是refNode爲null,那麼本方法與appendNode()方法功能相同。若是newChild節點在添加以前已經在文檔中存在,那麼就是修改節點的位置了。
l Node removeNode(Node oldChild):從當前節點中移除子元素oldChild。返回值爲被添加的子節點oldChild對象,方便使用鏈式操做。
l Node replaceNode(Node newChild, Node oldChild):將當前節點的子節點oldChild替換爲newChild。
Node獲取屬性集合方法,只有Element可使用:
l NamedNodeMap getAttributes():返回當前節點的屬性集合。NamedNodeMap表示屬性的集合,方法以下:
int getLength():獲取集合中屬性的個數;
Node item(int index):獲取指定下標位置上的屬性節點;
Node getNamedItem(String name):獲取指定名字的屬性節點;
Node removeNamedItem(String name):移除指定名字的屬性節點,返回值爲移除的屬性節點;
Node setNamedItem(Node arg):添加一個屬性節點,返回值爲添加的屬性節點。
Node的判斷方法:
l boolean hasChildNodes():判斷當前節點是否有子節點;
l boolean hasAttribute():判斷當前節點是否有屬性。
Docment方法介紹
建立節點方法:
l Attr createAttribute(String name):建立屬性節點;
l CDATASection createCDATASection(String data):建立CDATA段節點;
l Comment createComment(String data):建立註釋;
l Element createElement(String tagName):建立元素節點;
l Text createTextNode(String data):建立文本節點;
獲取子元素方法:
l Element getElementById(String elementId):經過元素的ID屬性獲取元素節點,若是沒有DTD指定屬性類型爲ID,那麼這個方法將返回null;
| NodeList getElementsByTagName(String tagName):獲取指定元素名稱的全部元素;
l Element getDocumentElement():獲取文檔元素,即獲取根元素。
文檔聲明相關方法:
l String getXmlVersion():獲取文檔聲明的version屬性值;
l String getXmlEncoding():獲取文檔聲明的encoding屬性值;
l String getXmlStandalone():獲取文檔聲明的standalone屬性值;
l void setXmlVersion():設置文檔聲明version屬性值;
l void setXmlStandalone():設置文檔聲明standalone屬性值。
獲取方法:
l NodeList getElementsByTagName(String tagName):獲取當前元素的指定元素名稱的全部子元素;
l String getTagName():獲取當前元素的元素名。調用元素節點的getNodeName()也是返回名;
屬性相關方法:
l String getAttribute(String name):獲取當前元素指定屬性名的屬性值;
l Attr getAttributeNode(String name):獲取當前元素指定屬性名的屬性節點;
l boolean hasAttribute(String name):判斷當前元素是否有指定屬性;
l void removeAttribute(String name):移除當前元素的指定屬性;
l void removeAttributeNode(Attr attr):移除當前元素的指定屬性;
l void setAttribute(String name, String value):爲當前元素添加或修改屬性;
l Attr setAttributeNode(Attr attr):爲當前元素添加或修改屬性,返回值爲添加的屬性;
l String getName():獲取當前屬性節點的屬性名;
l String getValue():獲取當前屬性節點的屬性值;
l void setValue(String value):設置當前屬性節點的屬性值;
l boolean isId():判斷當前屬性節點是否爲ID類型屬性。
SAXParser 解析器類
SAXParserFactory 解析器工廠
SAX是事件驅動型XML解析的一個標準接口
對文檔進行順序掃描,當掃描到文檔(document)開始與結束、元素(element)開始與結束、文檔(document)結束等地方時通知事件處理函數
咱們須要作的就是實現這些回調的方法體
示例:
public static void SaxParse() throws Exception { //建立解析器工廠 SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); //建立解析器 SAXParser saxParser = saxParserFactory.newSAXParser(); //執行parse方法 此方法依賴DefaultHandler,因此須要自定義類實現DefaultHandler //其中qName 是標籤的名稱 saxParser.parse("src/dom/test.xml", new DefaultHandler() { @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { System.out.println("<"+qName+">"); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { System.out.println("<"+qName+"/>"); } @Override public void characters(char[] ch, int start, int length) throws SAXException { System.out.print(new String(ch,start,length)); } }); }
DefaultHandler中還有不少的其餘方法
使用DOM解析主要就是獲取文檔後對於全部的節點進行操做
使用SAX解析主要就是根據各個事件發生時,進行所須要的響應
若是想要對文檔進行復雜的操做設置更多的須要查詢Node下相關的實現類 Document Text 等
若是想要對文檔進行復雜的篩選查詢,那麼須要精心的利用DefaultHandler處理各個事件
注意:既然說JAXP是一個接口規範,爲何能夠直接使用其來進行解析?
上面咱們已經提到了工廠類都是抽象類,並非本身實現的或者建立的,調用的newInstance建立的,他其實使用的是java提供給咱們的默認實現的解析器工做的
JAXP仍是接口規範,並非一組實現API
這是兩種第三方的解析工具 僅僅用於java
JDOM與DOM4J相比,DOM4J完勝!!!因此,咱們應該在從此的開發中,把DOM4J視爲首選。
DOM4J也是Hibernate使用的解析XML的方式
DOM4J首先會去經過JAXP的查找方法去查找解析器,若是找到解析器,那麼就使用之;
不然會使用本身的默認解析器Aelfred2。
https://github.com/dom4j/dom4j/wiki/FAQ 中有關於解析器的說明
DOM4J對DOM和SAX都提供了支持
能夠把DOM解析後的Document對象轉換成DOM4J的Document對象,固然了能夠把DOM4J的Document對象轉換成DOM的Document對象。
DOM4J使用SAX解析器把XML文檔加載到內存,生成DOM對象。固然也支持事件驅動的方式來解析XML文檔。
在DOM4J中,也有Node、Document、Element等接口,結構上與DOM中的接口比較類似。
但仍是有不少的區別:
在DOM4J中,全部XML組成部分都是一個Node,
其中Branch表示能夠包含子節點的節點,
例如Document和Element都是能夠有子節點的,它們都是Branch的子接口。
Attribute是屬性節點,CharacterData是文本節點,
文本節點有三個子接口,分別是CDATA、Text、Comment。
dom4J 官網 https://dom4j.github.io/
剛纔提到的工做原理
DOM4J使用SAX解析器把XML文檔加載到內存,生成DOM對象。固然也支持事件驅動的方式來解析XML文檔。
這句話是重點,他兩種解析方式均可以,並且,他是使用的SAX解析方式 建立了一棵DOM4J樹,此樹中的對象 能夠轉換成DOM樹中的對象
dom4j 2.1.1 API
https://dom4j.github.io/javadoc/2.1.1/overview-summary.html
第三方的工具使用必然須要查看他的介紹方法
基本的使用在官網上已經有了很清晰的介紹
官網 https://dom4j.github.io/
獲取指定元素標籤的內容
//查詢元素
public static void dom4jParseSelectNames() throws Exception { //1.導入包 import org.dom4j.io.SAXReader; //2.建立解析器 SAXReader saxReader = new SAXReader(); //3.使用解析器解析文檔 Document document = saxReader.read("src/dom/test.xml"); //4.獲得根節點 Element root = document.getRootElement(); //5.獲得指定元素的列表 List<Element> list = root.elements("student"); //6.遍歷list for (Element element : list) { //element是每個student元素 獲得student下面的name元素 Element name = element.element("name"); //獲得name裏面的值 String s = name.getText(); System.out.println(s); } } }
//增長一個元素
public static void dom4jParseAdd() throws Exception { //1.導入包 import org.dom4j.io.SAXReader; //2.建立解析器 SAXReader saxReader = new SAXReader(); //3.使用解析器解析文檔 Document document = saxReader.read("src/dom/test.xml"); //4.獲得根節點 Element root = document.getRootElement(); //5.獲得第一個student元素 Element studentElement = root.element("student"); //6.在student下面直接添加元素 Element sexElement = studentElement.addElement("sex"); //7.在sex下面添加文本 sexElement.setText("男"); //8.回寫數據 OutputFormat format = OutputFormat.createPrettyPrint(); XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/dom/test.xml"), format); xmlWriter.write(document); xmlWriter.close(); }
使用Dom4J格式都沒有變亂
XPath 使用路徑表達式在 XML 文檔中進行導航
XPath 包含一個標準函數庫
XPath 是 XSLT 中的主要元素
XPath 是一個 W3C 標準
http://www.w3school.com.cn/xpath/index.asp
XPath即爲XML路徑語言(XML Path Language),它是一種用來肯定XML文檔中某部分位置的語言。
XPath基於XML的樹狀結構,提供在數據結構樹中找尋節點的能力。
起初 XPath 的提出的初衷是將其做爲一個通用的、介於XPointer與XSL間的語法模型。可是 XPath 很快的被開發者採用來看成小型查詢語言。
就按照他的名字XML Path Language 理解就能夠徹底掌握這個概念
在 XPath 中,有七種類型的節點:元素、屬性、文本、命名空間、處理指令、註釋以及文檔節點(或稱爲根節點)。
類型都是節點類型的
其中直接值也就是常量 ,好比xml中的<year>2018</year> 2018就是基本值 原子值
節點之間的相互關係有 :
父 每一個元素以及屬性都有一個父。
子 元素節點可有零個、一個或多個子。
同胞 擁有相同的父的節點
先輩 某節點的父、父的父,等等
後代 某個節點的子,子的子,等等。
在DOM4J中,Node接口中的三個方法最爲經常使用:
List selectNodes(String xpathExpression):在當前節點中查找知足XPath表達式的全部子節點;
Node selectSingleNode(String xpathExpression):在當前節點中查找知足XPath表達式的第一個子節點;
String valueOf(String xpathExpression):在當前節點中查找知足XPath表達式的第一個子節點的文本內容;
語法格式能夠根據w3school中的語法形式進行選擇
http://www.w3school.com.cn/xpath/xpath_syntax.asp
想要在DOM4J中解析XPATH還須要另一個包 Jaxen
能夠去中央倉庫下載 或者隨便搜索一下 jaxen-1.1-beta-6.jar
不然就會報錯
Jaxen是一個用Java編寫的XPath引擎,用於處理各類基於XML的對象模型,如DOM,dom4j和JDOM以及Java Bean。
public static void dom4jParseXpath() throws Exception { //1.導入包 import org.dom4j.io.SAXReader; //2.建立解析器 SAXReader saxReader = new SAXReader(); //3.使用解析器解析文檔 Document document = saxReader.read("src/dom/test.xml"); //4.獲得根節點 List<Node> nodes = document.selectNodes("//name"); //5.遍歷list for (Node node : nodes) { //獲得name裏面的值 String s = node.getText(); System.out.println(s); } System.out.println("---------"); List<Node> nodess = document.selectNodes("//student"); //5.遍歷list for (Node node : nodess) { //獲得name裏面的值 String s = node.getStringValue(); System.out.println(s); } } }