JavaWeb筆記六:dom&xml

在這裏插入圖片描述

1、schema約束

dtd語法: <!ELEMENT 元素名稱 約束>
** schema符合xml的語法,xml語句
** 一個xml中可以有多個schema,多個schema使用名稱空間區分(類似於java包名)
** dtd裏面有PCDATA類型,但是在schema裏面可以支持更多的數據類型
	*** 比如 年齡 只能是整數,在schema可以直接定義一個整數類型
*** schema語法更加複雜,schema目前不能替代dtd

2、schema的快速入門

* 創建一個schema文件 後綴名是 .xsd
	** 根節點 <schema>
** 在schema文件裏面
	** 屬性  xmlns="http://www.w3.org/2001/XMLSchema"
		- 表示當前xml文件是一個約束文件
	** targetNamespace="http://www.itcast.cn/20151111"
		- 使用schema約束文件,直接通過這個地址引入約束文件
	** elementFormDefault="qualified"
步驟
	(1)看xml中有多少個元素
		<element>
	(2)看簡單元素和複雜元素
		* 如果複雜元素
			<complexType>
				<sequence>
					子元素
				</sequence>
		</complexType>
	(3)簡單元素,寫在複雜元素的
		<element name="person">
		<complexType>
		<sequence>
				<element name="name" type="string"></element>
				<element name="age" type="int"></element>
		</sequence>
		</complexType>
		</element>

	(4)在被約束文件裏面引入約束文件
		<person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns="http://www.itcast.cn/20151111"
		xsi:schemaLocation="http://www.itcast.cn/20151111 1.xsd">

		** xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
			-- 表示xml是一個被約束文件
		** xmlns="http://www.itcast.cn/20151111"
			-- 是約束文檔裏面 targetNamespace
		** xsi:schemaLocation="http://www.itcast.cn/20151111 1.xsd">
			-- targetNamespace 空格  約束文檔的地址路徑
	

* <sequence>:表示元素的出現的順序
<all>: 元素只能出現一次
<choice>:元素只能出現其中的一個
maxOccurs="unbounded": 表示元素的出現的次數
<any></any>:表示任意元素

* 可以約束屬性
	* 寫在複雜元素裏面
	***寫在 </complexType>之前
	--
	<attribute name="id1" type="int" use="required"></attribute>
		- name: 屬性名稱
		- type:屬性類型 int stirng
		- use:屬性是否必須出現 required

* 複雜的schema約束
	<company xmlns = "http://www.example.org/company"
xmlns:dept="http://www.example.org/department"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.org/company company.xsd http://www.example.org/department department.xsd" 

  * 引入多個schema文件,可以給每個起一個別名

<employee age="30">
	<!-- 部門名稱 --> 
	<dept:name>100</dept:name>
	* 想要引入部門的約束文件裏面的name,使用部門的別名 detp:元素名稱
	<!-- 員工名稱 -->
	<name>王曉曉</name>   
</employee>

3、sax解析的原理(********)

* 解析xml有兩種技術 dom 和sax

* 根據xml的層級結構在內存中分配一個樹形結構
** 把xml中標籤,屬性,文本封裝成對象

* sax方式:事件驅動,邊讀邊解析
* 在javax.xml.parsers包裏面
	** SAXParser
		此類的實例可以從 SAXParserFactory.newSAXParser() 方法獲得
		- parse(File f, DefaultHandler dh) 
			* 兩個參數
			** 第一個參數:xml的路徑
			** 事件處理器

	** SAXParserFactory
		實例 newInstance() 方法得到
* sax執行過程
	* 當解析到開始標籤時候,自動執行startElement方法
	* 當解析到文本時候,自動執行characters方法
	* 當解析到結束標籤時候,自動執行endElement方法

4、使用jaxp的sax方式解析xml(會寫*)

* sax方式不能實現增刪改操作,只能做查詢操作
** 打印出整個文檔
*** 執行parse方法,第一個參數xml路徑,第二個參數是 事件處理器
	*** 創建一個類,繼承事件處理器的類,
	***重寫裏面的三個方法

 * 獲取到所有的name元素的值
	** 定義一個成員變量 flag= false
	** 判斷開始方法是否是name元素,如果是name元素,把flag值設置成true
	** 如果flag值是true,在characters方法裏面打印內容
	** 當執行到結束方法時候,把flag值設置成false

 * 獲取第一個name元素的值
	** 定義一個成員變量 idx=1
	** 在結束方法時候,idx+1 idx++
	** 想要打印出第一個name元素的值,
		- 在characters方法裏面判斷,
		-- 判斷flag=true 並且 idx==1,在打印內容

5、使用dom4j解析xml

* dom4j,是一個組織,針對xml解析,提供解析器 dom4j

* dom4j不是javase的一部分,想要使用第一步需要怎麼做?
	*** 導入dom4j提供jar包
	-- 創建一個文件夾 lib
	-- 複製jar包到lib下面,
	-- 右鍵點擊jar包,build path -- add to build path
	-- 看到jar包,變成奶瓶樣子,表示導入成功

* 得到document
	 SAXReader reader = new SAXReader();
         Document document = reader.read(url);
* document的父接口是Node
	* 如果在document裏面找不到想要的方法,到Node裏面去找

* document裏面的方法 getRootElement() :獲取根節點 返回的是Element

* Element也是一個接口,父接口是Node
	- Element和Node裏面方法
	** getParent():獲取父節點
	** addElement:添加標籤

	* element(qname)
		** 表示獲取標籤下面的第一個子標籤
		** qname:標籤的名稱
	* elements(qname)
		** 獲取標籤下面是這個名稱的所有子標籤(一層)
		** qname:標籤名稱
	* elements()
		** 獲取標籤下面的所有一層子標籤

6、使用dom4j查詢xml

* 解析是從上到下解析
* 查詢所有name元素裏面的值
	/*
		1、創建解析器
		2、得到document
		3、得到根節點  getRootElement() 返回Element

		4、得到所有的p1標籤
			* elements("p1") 返回list集合
			* 遍歷list得到每一個p1
		5、得到name
			* 在p1下面執行 element("name")方法 返回Element
		6、得到name裏面的值
			* getText方法得到值
	*/

* 查詢第一個name元素的值
	/*
	 * 1、創建解析器
	 * 2、得到document
	 * 3、得到根節點
	 * 
	 * 4、得到第一個p1元素  
		** element("p1")方法 返回Element
	 * 5、得到p1下面的name元素
		** element("name")方法 返回Element
	 * 6、得到name元素裏面的值
		** getText方法
	 * */
* 獲取第二個name元素的值
	/*
	 * 1、創建解析器
	 * 2、得到document
	 * 3、得到根節點
	 * 
	 *  4、得到所有的p1 
		** 返回 list集合
	 *  5、遍歷得到第二個p1
		** 使用list下標得到 get方法,集合的下標從 0 開始,想要得到第二個值,下標寫 1 
	 *  6、得到第二個p1下面的name
		** element("name")方法 返回Element
	 *  7、得到name的值
		** getText方法
	 * */

7、使用dom4j實現添加操作

* 在第一個p1標籤末尾添加一個元素 <sex>nv</sex>
* 步驟
	/*
	 * 1、創建解析器
	 * 2、得到document
	 * 3、得到根節點
	 * 
	 * 4、獲取到第一個p1
		* 使用element方法
	 * 5、在p1下面添加元素
		* 在p1上面直接使用 addElement("標籤名稱")方法 返回一個Element

	 * 6、在添加完成之後的元素下面添加文本
	 *	在sex上直接使用 setText("文本內容")方法
	 * 7、回寫xml
		* 格式化 OutputFormat,使用 createPrettyPrint方法,表示一個漂亮的格式
		* 使用類XMLWriter 直接new 這個類 ,傳遞兩個參數
			*** 第一個參數是xml文件路徑 new FileOutputStream("路徑")
			*** 第二個參數是格式化類的值
	 * */

8、使用dom4j實現在特定位置添加元素

* 在第一個p1下面的age標籤之前添加 <school>ecit.edu.cn</schlool>
* 步驟
    /*
	 * 1、創建解析器
	 * 2、得到document
	 * 3、得到根節點
	 * 4、獲取到第一個p1
	 * 
	 * 5、獲取p1下面的所有的元素
	 * 		** elements()方法 返回 list集合

	 *      ** 使用list裏面的方法,在特定位置添加元素
	 *		** 首先創建元素 在元素下面創建文本
				- 使用DocumentHelper類方法createElement創建標籤
				- 把文本添加到標籤下面 使用 setText("文本內容")方法

	 *      	*** list集合裏面的 add(int index, E element)
	 *      		- 第一個參數是 位置 下標,從0開始
	 *      		- 第二個參數是 要添加的元素
	 * 6、回寫xml
	 * */

** 可以對得到document的操作和 回寫xml的操作,封裝成方法
** 也可以把傳遞的文件路徑,封裝成一個常量
*** 好處:可以提高開發速度,可以提交代碼可維護性
	- 比如想要修改文件路徑(名稱),這個時候只需要修改常量的值就可以了,其他代碼不需要做任何改變

9、使用dom4j實現修改節點的操作

* 修改第一個p1下面的age元素的值 <age>30</age>
* 步驟
/*
	 * 1、得到document
	 * 2、得到根節點,然後再得到第一個p1元素
	 * 3、得到第一個p1下面的age
		element("")方法
	 * 4、修改值是 30
	 *	* 使用setText("文本內容")方法
	 * 5、回寫xml
	 * 
	 * */

10、使用dom4j實現刪除節點的操作

* 刪除第一個p1下面的<school>ecit</school>元素
* 步驟
/*
	 * 1、得到document
	 * 2、得到根節點
	 * 3、得到第一個p1標籤
	 * 4、得到第一個p1下面的school元素

	 * 5、刪除(使用p1刪除school)
	 *	* 得到school的父節點
			- 第一種直接得到p1
			- 使用方法 getParent方法得到
		* 刪除操作
			- 在p1上面執行remove方法刪除節點
	 * 6、回寫xml
	 * */

11、使用dom4j獲取屬性的操作

* 獲取第一個p1裏面的屬性id1的值
* 步驟
/*
	 * 1、得到document
	 * 2、得到根節點
	 * 3、得到第一個p1元素
	 * 4、得到p1裏面的屬性值
		- p1.attributeValue("id1");
		- 在p1上面執行這個方法,裏面的參數是屬性名稱
	 * */

12、使用dom4j支持xpath的操作

* 可以直接獲取到某個元素 

* 第一種形式
	/AAA/DDD/BBB: 表示一層一層的,AAA下面 DDD下面的BBB
* 第二種形式
	//BBB: 表示和這個名稱相同,表示只要名稱是BBB,都得到
* 第三種形式
	/*: 所有元素
* 第四種形式
	** BBB[1]: 表示第一個BBB元素
	×× BBB[last()]:表示最後一個BBB元素
* 第五種形式
	** //BBB[@id]: 表示只要BBB元素上面有id屬性,都得到
* 第六種形式
	** //BBB[@id='b1'] 表示元素名稱是BBB,在BBB上面有id屬性,並且id的屬性值是b1

13、使用dom4j支持xpath具體操作

** 默認的情況下,dom4j不支持xpath
** 如果想要在dom4j裏面使用xpath
	* 第一步需要,引入支持xpath的jar包,使用 jaxen-1.1-beta-6.jar
	** 需要把jar包導入到項目中

** 在dom4j裏面提供了兩個方法,用來支持xpath
	*** selectNodes("xpath表達式")
		- 獲取多個節點
	*** selectSingleNode("xpath表達式")
		- 獲取一個節點

** 使用xpath實現:查詢xml中所有name元素的值
	** 所有name元素的xpath表示: //name
	** 使用selectNodes("//name");
	** 代碼和步驟
	/*
	 * 1、得到document
	 * 2、直接使用selectNodes("//name")方法得到所有的name元素
	 * 
	 * */
		//得到document
		Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
		//使用selectNodes("//name")方法得到所有的name元素
		List<Node> list = document.selectNodes("//name");
		//遍歷list集合
		for (Node node : list) {
			//node是每一個name元素
			//得到name元素裏面的值
			String s = node.getText();
			System.out.println(s);
		}

** 使用xpath實現:獲取第一個p1下面的name的值
	* //p1[@id1='aaaa']/name
	* 使用到 selectSingleNode("//p1[@id1='aaaa']/name")
	* 步驟和代碼
	/*
	 * 1、得到document
	 * 2、直接使用selectSingleNode方法實現
	 * 	- xpath : //p1[@id1='aaaa']/name
	 * */
	//得到document
	Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
	//直接使用selectSingleNode方法實現
	Node name1 = document.selectSingleNode("//p1[@id1='aaaa']/name"); //name的元素
	//得到name裏面的值
	String s1 = name1.getText();
	System.out.println(s1);

14、實現簡單的學生管理系統

** 使用xml當做數據,存儲學生信息

** 創建一個xml文件,寫一些學生信息

** 增加操作
	/*
	 * 1、創建解析器
	 * 2、得到document
	 * 3、獲取到根節點
	 * 4、在根節點上面創建stu標籤
	 * 5、在stu標籤上面依次添加id name age
		** addElement方法添加
	 * 6、在id name age上面依次添加值
	 *	** setText方法
	 * 7、回寫xml
	 * */

** 刪除操作(根據id刪除)
	/*
	 * 1、創建解析器
	 * 2、得到document
	 * 
	 * 3、獲取到所有的id	
	 * 	使用xpath //id 返回 list集合
	 * 4、遍歷list集合
	 * 5、判斷集合裏面的id和傳遞的id是否相同
	 * 6、如果相同,把id所在的stu刪除
	 * 
	 * */
	
** 查詢操作(根據id查詢)
	/*
	 * 1、創建解析器
	 * 2、得到document
	 * 
	 * 3、獲取到所有的id
	 * 4、返回的是list集合,遍歷list集合
	 * 5、得到每一個id的節點
	 * 6、id節點的值
	 * 7、判斷id的值和傳遞的id值是否相同
	 * 8、如果相同,先獲取到id的父節點stu
	 * 9、通過stu獲取到name age值

	 ** 把這些值封裝到一個對象裏面 返回對象
	 * 
	 * */
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章