day22_XML_XML約束
思維導(dǎo)圖

復(fù)習(xí)
1.知識點差不多都理解,不知道以后干啥用的,太多了消化不良
給框架用的!! 慢慢消化!!!
反射:
1.如何獲取Class對象
類名.class
對象名.getClass();
Class.forName("包名.類名")
2.如何通過反射獲取構(gòu)造方法,并使用構(gòu)造方法
Class對象.getConstructor(參數(shù)類型.class,..);
Class對象.getConstructors();
Class對象.getDeclaredConstructor(參數(shù)類型.class,..);
Class對象.getDeclaredConstructors();
Constructor對象.setAccessible(true);
Constructor對象.newInstance(參數(shù));
3.如果通過反射獲取成員方法,并使用成員方法
Class對象.getMethod(String name,參數(shù)類型.class,..);
Class對象.getMethods(); //獲取"public"修飾的所有方法(包括父類繼承的)
Class對象.getDeclaredMethod(String name,參數(shù)類型.class,..);
Class對象.getDeclaredMethods();//獲取"任意修飾"的所有方法(不包括父類繼承的)
Method對象.setAccessible(true);
Method對象.invoke(對象名,參數(shù));
注解:
1.定義注解
public @interface 注解名{
數(shù)據(jù)類型 屬性名();
數(shù)據(jù)類型 屬性名() default 默認(rèn)值;
}
2.使用注解
默認(rèn)情況下,注解可以用在包上,類上,方法上(構(gòu)造方法/普通方法),變量上(成員變量/局部變量)
使用格式:
@注解名(必須給沒有默認(rèn)值的屬性賦值,有默認(rèn)值可以賦值也可以不賦值)
3.特殊的屬性:value
a.如果注解只有一個屬性,并且叫做value,那么使用該注解時,可以省略value的名字,直接寫value的值
b.如果除了value之外還有其他屬性,必須其他屬性有默認(rèn)值,且不重寫賦值,
那么使用該注解時,可以省略value的名字,直接寫value的值
4.元注解(了解)
5.注解的解析(了解)
今日內(nèi)容
- XML
- XML約束
XML的學(xué)習(xí)
XML概念
XML的介紹
XML 指可擴(kuò)展標(biāo)記語言(EXtensible Markup Language)
XML 是一種標(biāo)記語言,很類似 HTML,HTML文件也是XML文檔 <標(biāo)簽名></標(biāo)簽名>
XML 的設(shè)計宗旨是傳輸數(shù)據(jù),而非顯示數(shù)據(jù)
XML 標(biāo)簽沒有被預(yù)定義。您需要自行定義標(biāo)簽
XML 被設(shè)計為具有自我描述性(就是易于閱讀)。
XML 是 W3C 的推薦標(biāo)準(zhǔn)
XML的版本
W3C在1988年2月發(fā)布1.0版本,2004年2月又發(fā)布1.1版本,但因為1.1版本不能向下兼容1.0版本,所以1.1沒有人用。同時,在2004年2月W3C又發(fā)布了1.0版本的第三版。我們要學(xué)習(xí)的還是1.0版本。
XML與HTML的主要差異
- XML 不是 HTML 的替代
- XML 和 HTML 為不同的目的而設(shè)計。
- XML 被設(shè)計為傳輸和存儲數(shù)據(jù)(現(xiàn)在用的json更多),其焦點是數(shù)據(jù)的內(nèi)容。
- HTML 被設(shè)計用來顯示數(shù)據(jù),其焦點是數(shù)據(jù)的外觀。
- HTML 旨在顯示信息,而 XML 旨在傳輸信息。
XML的入門小案例
<?xml version="1.0" encoding="UTF-8"?>
<person id="110">
<age>18</age> <!--年齡-->
<name>張三</name> <!--姓名-->
<sex/> <!--性別-->
</person>
XML的作用
- XML在企業(yè)開發(fā)中主要有兩種應(yīng)用場景:
- XML可以存儲數(shù)據(jù) , 作為數(shù)據(jù)交換的載體(使用XML格式進(jìn)行數(shù)據(jù)的傳輸)。(現(xiàn)在使用的json更多)
- XML也可以作為配置文件,例如后面框架階段我們學(xué)習(xí)的Spring框架的配置(applicationContext.xml)都是通過XML進(jìn)行配置的(企業(yè)開發(fā)中經(jīng)常使用的)
XML的語法
XML的組成元素
XML文件中常見的組成元素有:文檔聲明、元素、屬性、注釋、轉(zhuǎn)義字符、字符區(qū)。
-
文檔聲明: 作用是說明這是個XML文件
- 必須寫在XML文件的0行0列(左上角)
- 固定格式:
<?xml version="1.0" encoding="UTF-8" ?>表示為版本, 編碼
-
元素/標(biāo)簽
-
格式:
<標(biāo)簽名> </標(biāo)簽名> 或者當(dāng)沒有內(nèi)容時可以寫成 <標(biāo)簽名/>
標(biāo)簽有三部分組成: 由開始標(biāo)簽、元素體、結(jié)束標(biāo)簽組成。
元素體:元素體可以是元素,也可以是文本,例如:
<person><name>張三</name></person>空元素:空元素只有標(biāo)簽,而沒有結(jié)束標(biāo)簽,但元素必須自己閉合,例如:
<sex/>-
元素/標(biāo)簽的命名要求
- 區(qū)分大小寫
- 不能使用空格,不能使用冒號等特殊符號
- 不建議以XML、xml、Xml開頭
格式化良好的XML文檔,有且僅有一個根元素。根元素是指最外層標(biāo)簽
-
-
屬性
<person id="110">- 屬性是元素的一部分,它必須出現(xiàn)在元素的開始標(biāo)簽中
- 屬性的定義格式:屬性名=“屬性值”,其中屬性值必須使用單引或雙引號括起來
- 一個元素可以有0~N個屬性,但一個元素中不能出現(xiàn)同名屬性
- 屬性名不能使用空格 , 不要使用冒號等特殊字符,且必須以字母開頭
-
注釋
``
-
轉(zhuǎn)義字符
需要用的一些特殊字符時, 可能直接寫上這些字符會成為XML語法的一部分, 所以使用轉(zhuǎn)義字符
字符 預(yù)定義的轉(zhuǎn)義字符 說明 < <小于 > >大于 " "雙引號 ' '單引號 & &和號 如下需要把 < 改為
<<message>if salary < 1000 then</message><message>if salary < 1000 then</message> -
字符區(qū)
- 需要大量轉(zhuǎn)義字符時, 使用格式
<![CDATA[ 文本數(shù)據(jù) ]]>- CDATA 指的是不應(yīng)由 XML 解析器進(jìn)行解析的文本數(shù)據(jù)(Unparsed Character Data)
- CDATA 部分由 "" 結(jié)束;
-
注意:
CDATA 部分不能包含字符串 "]]>"。也不允許嵌套的 CDATA 部分。
標(biāo)記 CDATA 部分結(jié)尾的 "]]>" 不能包含空格或折行。
XML文件的約束
在XML技術(shù)里,可以編寫一個文檔來約束一個XML文檔的書寫規(guī)范,這稱之為XML約束。
常見的xml約束:DTD、Schema
DTD約束
-
概念:
DTD約束: 成為文檔類型定義, 規(guī)定我們在編寫XML時具體的標(biāo)簽,子標(biāo)簽, 屬性等
-
DTD約束簡單入門
- 復(fù)制編寫好的dtd文件到指定文件夾下,
- 新建需要編寫的XML文件
- 將dtd文件中引用規(guī)則寫入新建的XML文件中 如
<!DOCTYPE 書架 SYSTEM "bookshelf.dtd"> - 根據(jù)dtd文件規(guī)則編寫xml內(nèi)容
在企業(yè)實際開發(fā)中,我們很少自己編寫DTD約束文檔,通常情況下通過框架提供的DTD約束文檔編寫對應(yīng)的XML文檔。所以這一知識點的要求是可以根據(jù)DTD約束文檔內(nèi)容編寫XML文檔。
-
DTD的語法
-
DTD的引入
-
內(nèi)部DTD(把DTD內(nèi)容直接寫在XML里面. 這種方法只對當(dāng)前XML文件有效)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE 根元素 [...//具體語法]><!--內(nèi)部DTD--> <根元素> </根元素> -
外部DTD-本地(把DTD文檔放在本地系統(tǒng)上, 內(nèi)部人自己使用)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE 根元素 SYSTEM "bookshelf.dtd"><!--外部本地DTD--> <根元素> </根元素> -
外部DTD-公共(把DTD文檔放在網(wǎng)絡(luò)上, 一般框架使用較多)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> </web-app>
-
-
DTD中的數(shù)量詞
數(shù)量詞符號 含義 * 表示元素出現(xiàn)0到多個 + 表示元素出現(xiàn)至少1個 ? 表示元素可以是0或1個 , 表示元素需要按照順序顯示 | 表示元素需要選擇其中的某一個 -
DTD中的元素聲明
-
語法
<!ELEMENT 標(biāo)簽名字 標(biāo)簽類型> -
標(biāo)簽類型有三種
(#PCDATA) 被解釋的字符串?dāng)?shù)據(jù)
EMPTY 即空元素,例如
ANY 即任意類型-
<!ELEMENT 書名 (#PCDATA)> <!--"書名"元素體為字符串?dāng)?shù)據(jù)--> <!ELEMENT 作者 (#PCDATA)> <!--"作者"元素體為字符串?dāng)?shù)據(jù)--> <!ELEMENT 售價 (#PCDATA)> <!--"售價"元素體為字符串?dāng)?shù)據(jù)--> <!ELEMENT 出版日期 ANY> <!--"出版日期"元素體為任意類型--> <!ELEMENT 版本號 EMPTY> <!--"版本號"元素體為空元素-->
-
-
-
DTD中的屬性聲明
<!ATTLIST 書 <!--設(shè)置"書"元素的的屬性列表--> id ID #REQUIRED <!--"id"屬性值為必須有--> 編號 CDATA #IMPLIED <!--"編號"屬性可有可無--> 出版社 (清華|北大|傳智播客) "傳智播客"<!--"出版社"屬性值是枚舉值,默認(rèn)為“傳智播客”--> type CDATA #FIXED "IT" <!--"type"屬性為文本字符串并且固定值為"IT"--> >
schema約束
-
概念
Schema 語言也可作為 XSD(XML Schema De?nition)。
Schema 比DTD強(qiáng)大,是DTD代替者。
Schema 本身也是XML文檔,Schema文檔擴(kuò)展名為xsd,而不是xml。
Schema 功能更強(qiáng)大,數(shù)據(jù)類型約束更完善。 -
schema使用
復(fù)制schema約束文件中指定的代碼到需要編寫的xml文件中.
我們復(fù)制過來的是根標(biāo)簽的開始標(biāo)簽, 需要補(bǔ)充結(jié)束標(biāo)簽
根據(jù)約束編寫xml文件
-
schema中的 名稱空間
相當(dāng)于導(dǎo)包一樣, 指定是哪個文件中的標(biāo)簽名. 名稱空間就是用來處理元素和屬性的名稱沖突問題,與Java中的包是同一用途。如果每個元素和屬性都有自己的名稱空間,那么就不會出現(xiàn)名字沖突問題,就像是每個類都有自己所在的包一樣,那么類名就不會出現(xiàn)沖突。如xsd文件中的
<xs:element name='書名' -
schema 學(xué)習(xí)的要求
schema功能比dtd強(qiáng)大,但是編寫要比DTD復(fù)雜,同樣以后我們在企業(yè)開發(fā)中也很少會自己編寫schema文件,需要學(xué)會框架提供的xsd約束去編寫xml.
XML解析
XML解析概述
就是將XML文件中保存的數(shù)據(jù)讀取出來
解析方式, 解析器,解析開發(fā)包
解析方式
-
DOM解析: 要求解析器把整個XML文檔裝載到內(nèi)存,并解析成一個Document對象
- 優(yōu)點:元素與元素之間保留結(jié)構(gòu)關(guān)系,故可以進(jìn)行增刪改查操作。
- 缺點:XML文檔過大,可能出現(xiàn)內(nèi)存溢出
-
SAX:是一種速度更快,更有效的方法。它逐行掃描文檔,一邊掃描一邊解析。并以事件驅(qū)動的方式進(jìn)行具體解析,每執(zhí)行一行,都觸發(fā)對應(yīng)的事件。
- 優(yōu)點:處理速度快,可以處理大文件
- 缺點:只能讀,逐行后將釋放資源,解析操作繁瑣。
PULL:Android內(nèi)置的XML解析方式,類似SAX。
解析器
就是根據(jù)不同的解析方式提供具體實現(xiàn)。
解析開發(fā)包
對解析器的繁瑣細(xì)節(jié) 進(jìn)行了封裝. 方便開發(fā)人員根據(jù)API解析xml文件
- 常見的解析開發(fā)包
- JAXP:sun公司提供支持DOM和SAX開發(fā)包
- Dom4j:比較簡單的的解析開發(fā)包(常用)
- JDom:與Dom4j類似
- Jsoup:功能強(qiáng)大DOM方式的XML解析開發(fā)包,尤其對HTML解析更加方便(項目中講解)
Dom4J的基本使用
-
Dom4J 的基本原理
XML DOM 和 HTML DOM一樣,XML DOM 將整個XML文檔加載到內(nèi)存,生成一個DOM樹,并獲得一個Document對象,通過Document對象就可以對DOM進(jìn)行操作。以下面books.xml文檔為例。
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="0001">
<name>JavaWeb開發(fā)教程</name>
<author>張孝祥</author>
<sale>100.00元</sale>
</book>
<book id="0002">
<name>三國演義</name>
<author>羅貫中</author>
<sale>100.00元</sale>
</book>
</books>
- 結(jié)構(gòu)模型


DOM中的核心概念就是節(jié)點,在XML文檔中的元素、屬性、文本,在DOM中都是節(jié)點!所有的節(jié)點都封裝到了Document對象中。
-
引入dom4j的jar包
在模塊下創(chuàng)建一個lib文件夾(必須叫l(wèi)ib). 把第三方下的 dom4j 的jar包放入lib文件夾內(nèi)
將jar包加載到模塊依賴中
-
Dom4J的API
-
核心類: SAXReader
new SAXReader()構(gòu)造器Document read(String url)加載執(zhí)行xml文檔 -
Doucument對象的API
Element getRootElement()獲得根元素 -
Element對象的API
-
List elements([String ele] )獲得指定名稱的所有子元素??梢圆恢付Q(中括號內(nèi)可以不寫) -
Element element([String ele])獲得指定名稱第一個子元素。可以不指定名稱 -
String getName()獲得當(dāng)前元素的元素名 -
String attributeValue(String attrName)獲得指定屬性名的屬性值 -
String elementText(Sting ele)獲得指定名稱子元素的文本值 -
String getText()獲得當(dāng)前元素的文本內(nèi)容
-
-
-
Dom4J的代碼演示
首先將資料下的常用xml中"books.xml"放入項目目錄下
xml文件如下
<?xml version="1.0" encoding="UTF-8"?> <books> <book id="0001"> <name>JavaWeb開發(fā)教程</name> <author>張孝祥</author> <sale>100.00元</sale> </book> <book id="0002"> <name>三國演義</name> <author>羅貫中</author> <sale>100.00元</sale> </book> </books>java中解析xml文件如下
public class Demo { public static void main(String[] args) throws DocumentException { SAXReader reader = new SAXReader(); Document document = reader.read(Demo.class.getResourceAsStream("/books.xml //獲取根元素 books Element elemRoot = document.getRootElement(); //獲取根元素的所有子元素 book List<Element>list = elemRoot.elements(); //遍歷集合 獲取每一個book for(Element element : list){ //獲取book的id屬性 String id =element.attributeValue("id"); System.out.println("id : "+ id); //獲取book下的所有子元素 name,author,sale List<Element>listElem = element.elements(); //遍歷集合 獲取每一個子元素 for(Element elem : listElem){ //元素名 String name = elem.getName(); //文本值 String text = elem.getText(); System.out.println("--- " + name + " : " + text); } } } }
Dmo4J結(jié)合XPath解析XML
什么是XPath
XPath是XML 的路徑表達(dá)式, 可以快速從n層標(biāo)簽中選出需要的標(biāo)簽.(一般都是寫好的, 要會使用)
XPath使用步驟
- 具體步驟
- 導(dǎo)入jar包(dom4j和jaxen-1.1-beta-6.jar)
- 通過dom4j的SaxReader獲取Document對象
- 利用Xpath提供的api,結(jié)合xpaht的語法完成選取XML文檔元素節(jié)點進(jìn)行解析操作。
- 和XPath相關(guān)的Doucument的常用API
-
List selectNodes("XPath路徑表達(dá)式")獲取符合路徑表達(dá)式的所有元素集合 -
Element selectSingleNode("XPath路徑表達(dá)式")獲取符合路徑表達(dá)式的唯一元素
-
XPath路徑表達(dá)式的語法(了解就行)
-
絕對路徑表達(dá)式方式
格式: String xpath="/元素/子元素/子子元素...";
絕對路徑是以“/”開頭,一級一級描述標(biāo)簽的層級路徑就是絕對路徑,這里注意不可以跨層級
絕對路徑是從根元素開始寫路徑的,這里開頭的“/”代表HTML文檔根元素,所以在絕對路徑中不可以寫根元素路徑 -
相對路徑表達(dá)式
格式: String xpath1="子元素/子子元素...";//獲取相對當(dāng)前路徑元素里面的子元素的選取
-
全文搜索路徑表達(dá)式方式(常用的)
格式: String xpath1="http://子元素//子子元素";
一個“/”符號,代表逐級寫路徑
2個“//”符號,不用逐級寫路徑,可以直接選取到對應(yīng)的節(jié)點,是全文搜索匹配的不需要按照逐層級 -
謂語(條件篩選)
格式:
//元素[test() =value] 表示獲取元素的文本值為value的節(jié)點
String xpath1="http://元素[@attr1=value]";//獲取元素屬性attr1=value的元素
String xpath2="http://元素[@attr1>value]/@attr1"http://獲取元素屬性attr1>value的d的所有attr1的值
String xpath3="http://元素[@attr1=value]/text()";//獲取符合條件元素體的自有文本數(shù)據(jù)
String xpath4="http://元素[@attr1=value]/html()";//獲取符合條件元素體的自有html代碼數(shù)據(jù)。
String xpath3="http://元素[@attr1=value]/allText()";//獲取符合條件元素體的所有文本數(shù)據(jù)(包含子元素里面的文本)
Dom4J結(jié)合XPaht的代碼演示
public class DemoXpath {
public static void main(String[] args) throws Exception {
SAXReader reader = new SAXReader();
Document document = reader.read(Demo.class.getResourceAsStream("/books.xml"));
//獲取所有的book元素
List<Element> list = document.selectNodes("http://book");
for (Element ele: list) {
System.out.println(ele.attributeValue("id"));
}
//獲取id為0002的指定book元素的子標(biāo)簽name的內(nèi)容
Element ele = (Element)document.selectSingleNode("http://book[@id='0002']/name");
System.out.println(ele.getText());
}
}
今日總結(jié)
學(xué)習(xí)目標(biāo)
1.能夠說出XML的作用
是一種標(biāo)記語言,主要用于傳輸數(shù)據(jù)。
規(guī)范數(shù)據(jù)格式,使數(shù)據(jù)具有結(jié)構(gòu)性,便于讀寫。
多應(yīng)用于框架的配置文件。
2.了解XML的組成元素
文檔聲明、元素、屬性、注釋、轉(zhuǎn)義字符、字符區(qū)
文檔聲明
<?xml version="1.0" encoding="utf-8" ?>
1.文檔聲明必須從文檔的0行0列位置開始;
2.version:指定XML文檔版本,必備屬性,一般都是1.0
3.encoding:指定當(dāng)前文檔的編碼,可選屬性,默認(rèn)值是utf-8
元素
<元素名></元素名>
<元素名/>
1.元素名區(qū)分大小寫。
2.普通元素的結(jié)構(gòu)由開始標(biāo)簽、元素體、結(jié)束標(biāo)簽組成。
3.空元素可以沒有結(jié)束標(biāo)簽
4.元素體可以嵌套文本或其他元素。
<元素名>張三</元素名>
<元素名1>
<元素名2></元素名2>
<元素名3></元素名3>
</元素名1>
屬性
<元素名 屬性名="屬性值"></元素名>
1.屬性是元素的一部分,它必須出現(xiàn)在元素的開始標(biāo)簽內(nèi)。
2.屬性的定義格式:屬性名=“屬性值”,其中屬性值必須使用單引或雙引號括起來。
3.一個元素可以有多個屬性,但屬性不能同名。
4.屬性名必須以字母開頭。
注釋
<!--注釋內(nèi)容-->
注釋不能嵌套使用。
轉(zhuǎn)義字符
為了避免文檔結(jié)構(gòu)沖突,一些特殊符號需要使用轉(zhuǎn)義字符表示。
字符 轉(zhuǎn)義字符 說明
< < 小于
> > 大于
" " 雙引號
' ' 單引號
& & 和號
字符區(qū)
<![CDATA[
文本數(shù)據(jù)
]]>
CDATA中的文本會原樣輸出,便于直觀閱讀數(shù)據(jù)。
CDATA結(jié)構(gòu)不能嵌套。
3.能夠說出有哪些XML約束技術(shù)
DTD約束
schema約束
4.能夠說出解析XML文檔DOM方式原理
DOM解析原理:
解析器會把整個XML加載到內(nèi)存,并解析成一個文檔樹的結(jié)構(gòu),返回一個Document對象。
通過操作Document對象,就可以實現(xiàn)對XML文件的增刪改查。
5.能夠使用dom4j解析XML文檔
使用前需要在項目或模塊下添加dom4j-1.6.1.jar的開發(fā)包。
讀取XML,生成Document對象:
SAXReader reader = new SAXReader();
Doucument d = reader.read("xml文件地址")
獲取文檔根元素:
Element e = d.getRootElement();
操作Element對象:
List elements([String ele] ) 獲取當(dāng)前元素的所有直接子元素??梢圆恢付Q
Element element(String name) 獲得指定名稱第一個子元素。
String attributeValue(String attrName) 獲得指定屬性名的屬性值
String elementText(String ele) 獲得指定名稱子元素的文本值
String getName() 獲得當(dāng)前元素的元素名
String getText() 獲得當(dāng)前元素的文本內(nèi)容
6.能夠使用xpath解析XML或HTML文檔
需要導(dǎo)入的包:
dom4j-1.6.1.jar
jaxen-1.1-beta-6.jar
XPath使用路徑表達(dá)式來選取文檔中的元素或?qū)傩浴? 絕對路徑 :/根元素/子元素/子子元素...
相對路徑 :子元素/子子元素..
./子元素/子子元素..
全文搜索 : //子元素//子子元素
條件過濾: //元素[@屬性名=屬性值]
配合表達(dá)式查詢的常用方法:
獲取多個元素的集合:List selectNodes("xpath表達(dá)式")
獲取單個元素: Note selectSingleNode("xpath表達(dá)式")
綜合練習(xí)
根據(jù)要求,解析以下book.xml文檔
1. 找到id為002的書,并輸出書名
2. 查詢 category=計算機(jī) 的圖書的數(shù)量,并遍歷打印書名。
3. 查詢 name=紅樓夢 的書對應(yīng)的類別。(提示:獲取父類元素 getParent())。
4. 統(tǒng)計價格在50元以下的圖書數(shù)量。
5. 解析book.xml文檔,封裝到ArrayList<Book>集合中,再遍歷輸出集合的元素。
6. 修改作者為黑馬程序員的書本,改作者為:傳智播客,
7. 將修改后的xml寫出到當(dāng)前模塊src目錄下,文件名為book_v2.xml
book.xml
<?xml version="1.0" encoding="utf-8" ?>
<bookstore>
<book id="001" category="計算機(jī)">
<name>Java基礎(chǔ)案例</name>
<author>黑馬程序員</author>
<price>49</price>
</book>
<book id="002" category="計算機(jī)">
<name>MySQL數(shù)據(jù)庫原理</name>
<author>黑馬程序員</author>
<price>59</price>
</book>
<book id="003" category="計算機(jī)">
<name>數(shù)據(jù)結(jié)構(gòu)與算法</name>
<author>Allen</author>
<price>66</price>
</book>
<book id="004" category="文學(xué)">
<name>三國演義</name>
<author>羅貫中</author>
<price>39</price>
</book>
<book id="005" category="文學(xué)">
<name>紅樓夢</name>
<author>曹雪芹</author>
<price>39</price>
</book>
</bookstore>
Book類
public class Book {
private String id;
private String category;
private String name;
private String author;
private String price;
public Book() {
}
public Book(String id, String category, String name, String author, String price) {
this.id = id;
this.category = category;
this.name = name;
this.author = author;
this.price = price;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
@Override
public String toString() {
return "Book{" +
"id='" + id + '\'' +
", category='" + category + '\'' +
", name='" + name + '\'' +
", author='" + author + '\'' +
", price='" + price + '\'' +
'}';
}
}
解析代碼
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;
public class BookDemo {
public static void main(String[] args) throws Exception {
//讀取xml文件,返回DOM對象
SAXReader reader = new SAXReader();
Document d = reader.read("day22/src/book.xml");
//1. 找到id為002的書,并輸出書名
String name = d.selectSingleNode("http://book[@id='002']/name").getText();
System.out.println(name);
//2. 查詢 category=計算機(jī) 的圖書的數(shù)量,并遍歷打印書名。
List<Element> list = d.selectNodes("http://book[@category='計算機(jī)']");
System.out.println("數(shù)量為:"+list.size());
list.forEach(e->{
//String name2 = e.element("name").getText();
String name2 = e.elementText("name");//獲取每一個name元素的文本
System.out.println(name2);
});
//3. 查詢 name=紅樓夢 的書對應(yīng)的類別。(提示:獲取父類元素 getParent())。
//獲取元素<name>紅樓夢</name>
Element e = (Element)d.selectSingleNode("http://book/name[text()='紅樓夢']");
//獲取<name>元素的父標(biāo)簽<book>
Element parent = e.getParent();
//獲取屬性值
String category = parent.attributeValue("category");
System.out.println("紅樓夢的類別是:"+category);
//4. 統(tǒng)計價格在50元以下的圖書數(shù)量。
//獲取所有book的price元素,再獲取元素中的文本,即價格
List<Element> priceList = d.selectNodes("http://book/price");
int count = 0;
for(Element e2 : priceList){
String p = e2.getText();
Integer price = Integer.valueOf(p);
if(price<=50){
count++;
}
}
System.out.println("價格在50元以下的圖書數(shù)量:"+count);
//5. 解析book.xml文檔,封裝到ArrayList<Book>集合中,再遍歷輸出集合的元素。
List<Book> bookList = new ArrayList<>();
//獲取所有book元素的集合
List<Element> eList = d.selectNodes("http://book");
//遍歷每一個book元素
eList.forEach(e3->{
String id = e3.attributeValue("id");
String cate = e3.attributeValue("category");
String bookName = e3.elementText("name");//獲取e3元素的子元素name的文本
String author = e3.elementText("author");
String price = e3.elementText("price");
//創(chuàng)建Book對象
Book b = new Book(id,cate,bookName,author,price);
//添加到集合里
bookList.add(b);
});
//遍歷ArrayList<Book>集合
bookList.forEach(System.out::println);
//6. 修改作者為黑馬程序員的書本,改作者為:傳智播客
// 修改元素文本方法:setText("新內(nèi)容")
//獲取所有<author>黑馬程序員</author>元素
List<Element> listAut = d.selectNodes("http://book/author[text()='黑馬程序員']");
listAut.forEach(eAut->{
//修改作者
eAut.setText("傳智播客");
});
//7.將修改后的xml寫出到當(dāng)前模塊src目錄下,文件名為book_v2.xml
FileWriter f = new FileWriter("day22/src/book_v2.xml");
d.write(f);
//刷出數(shù)據(jù)并關(guān)閉流
f.flush();
f.close();
}
}