XML 簡介 可擴充标記型語言
html 裡面的标簽是固定的
XML 标簽可以自己來定義<person></person><貓></貓>
XML用途
可以用于顯示資料和存儲資料(主要功能是存儲)
XML 是w3c組織釋出的技術
1.1版本不能向下相容
XML應用
不同系統之間傳輸資料
QQ之間的資料傳輸
用了表示生活中有關系的資料
經常用在配置檔案
XML的文法
xml的文檔聲明
定義元素(标簽)
定義屬性
注釋
特殊字元
CDTAT區
PI指令
XML中文亂碼問題解決:儲存和執行編碼表需要一緻
XML元素的定義
标簽的定義 :标簽有開始必須有結束
标簽沒有内容 可以在标簽内結束
标簽可以嵌套 必須合理嵌套:不能交叉
XML把空格換行都當成内容來解析
<aa>aaaaa</aa>
<aa>aaaaa
<aa/>這倆個不一樣、
定義區分大小寫 不能以數字和下劃線開頭
不能以xml XML等開頭
不能包含空格 名稱中間不能包含冒号
XML屬性的定義
屬性定義的要求
一個标簽上可以有多個屬性
屬性名稱不能相同
屬性值一定要用引号
其他和元素定義相同
注釋不能嵌套
XML轉義字元
& --> &
< --> <
> --> >
" --> "
' --> &apos
XML的CDTAT區 解決頻繁轉義的操作
把需要轉義内容放入CDTAT區就不需要轉義
寫法 <![CDTAT[ 内容 ]]>
PI指令(處理指令)
可以在xml中設定樣式
寫法:<?xml-stylesheet type="text/css" href="css路徑" target="_blank" rel="external nofollow" >對中文不起作用
XML的限制
xml的限制技術 dtd限制 schema限制
dtd快速入門
·建立一個檔案 字尾為.dtd
·步驟 看xml中有多少元素 有幾個元素,寫幾個<!ELEMENT>
判斷元素書簡單元素還是複雜元素
簡單元素就是沒有子元素 <ELEMENT 元素名稱(#PCDATA)>
複雜元素就是有子元素 <!ELEMENT 元素名稱 (子元素)>
在xml中引入dtd檔案
<!DOCTYPE 根元素名稱 SYSTEM "dtd檔案路徑">
· 打開xml檔案使用浏覽器打開,浏覽器隻負責校驗xml文法 不檢驗限制
· 要檢驗xml限制,需要使用工具(myeclise)
dta的三種引入方式
<!DOCTYPE 根元素名稱 SYSTEM "dtd檔案路徑">
<!DOCTYPE 根元素名稱 [ DTD代碼 ]>
架構多使用<!DOCTYPE PUBLIC "dtd名稱" "dtd文檔url">
使用dtd定義元素
文法 <!ELEMENT 元素名稱 限制>
簡單元素#PCDATA 限制是字元串類型
EMPTY 元素為空
ANY:任意
複雜元素
<!ELEMENT 元素名稱 (子元素)>子元素隻能出現一次
+:表示一次或者多次
?:表示零次或者一次
*:表示任意次
子元素用|隔開 隻能出現任意一個
使用dtd定義屬性
文法: <! ATTLIST 元素名稱
屬性名稱 屬性類型 屬性的限制 >
屬性值類型 CDATA 文本字元串
枚舉 | 每次出現其中一個
ID 表示屬性取值不能重複
屬性限制設定說明
REQUIRED:該屬性必須出現
IMPLIED:該屬性可有可無
FIXED:屬性的取值為固定值
直接值:表示取值為該預設值
引入實體 定義<!ENTITY 實體名稱 "實體的值">
使用 &實體名稱
·注意 定義實體需要寫在dtd裡面
XML解析的簡介(寫到java代碼)
xml的解析方式 :dom 和 sax
使用dom解析xml 優點友善操作增删改查 缺點是容易記憶體溢出
使用sam解析: 采用事件驅動 邊讀邊解析 不會記憶體溢出 但不能實作增删改操作
解析xml ,首先需要解析器
不同的公司群組織 提供了api方式提供
sun:針對dom 和sax的解析器 jaxp
dom4j: dom4j(實際開發中使用最多)
jdom: jdom
jaxp的api檢視發現
jaxp是javase的一部分
jaxp解析器在jdk的javax.xml.parsers包裡
四個類分别針對dom和sax解析使用的類
dom DocumentBuilder :解析器類 (抽象類)
可以從DocumentBuilderFactory.newDocumentBuilder()中擷取
一個解析xml的方法 parse(String url) 傳回Document整個文檔
- 傳回的document是一個接口,父節點是Node,如果在document裡面找不到想要的方法,到Node裡面去找
- 在document裡面方法
getElementsByTagName(String tagname)
-- 這個方法可以得到标簽
-- 傳回集合 NodeList
createElement(String tagName)
-- 建立标簽
createTextNode(String data)
-- 建立文本
appendChild(Node newChild)
-- 把文本添加到标簽下面
removeChild(Node oldChild)
-- 删除節點
getParentNode()
-- 擷取父節點
NodeList list
- getLength() 得到集合的長度
- item(int index)下标取到具體的值
for(int i=0;i<list.getLength();i++) {
list.item(i)
}
getTextContent()
- 得到标簽裡面的内容
DocumentBuilderFactory 解析器工廠(抽象類)
可以從newInstance()擷取
sax SAXparser解析器類
SAXparserFactory 解析器工廠
使用jaxp實作查詢操作
*** 查詢xml中所有的name元素的值
* 步驟
//查詢所有name元素的值
*** 查詢xml中第一個name元素的值
* 步驟
使用jaxp添加節點
*** 在第一個p1下面(末尾)添加 <sex>nv</sex>
**步驟
使用jaxp修改節點
*** 修改第一個p1下面的sex内容是nan
** 步驟
使用jaxp删除節點
*** 删除<sex>nan</sex>節點
** 步驟
使用jaxp周遊節點
** 把xml中的所有元素名稱列印出來
** 步驟
** 周遊的方法
//遞歸周遊的方法
private static void list1(Node node) {
//判斷是元素類型時候才列印
if(node.getNodeType() == Node.ELEMENT_NODE) {
System.out.println(node.getNodeName());
}
//得到一層子節點
NodeList list = node.getChildNodes();
//周遊list
for(int i=0;i<list.getLength();i++) {
//得到每一個節點
Node node1 = list.item(i);
//繼續得到node1的子節點
//node1.getChildNodes()
list1(node1);
}
}
schema限制
dtd文法: <!ELEMENT 元素名稱 限制>
** schema符合xml的文法,xml語句
** 一個xml中可以有多個schema,多個schema使用名稱空間區分(類似于java包名)
** dtd裡面有PCDATA類型,但是在schema裡面可以支援更多的資料類型
*** 比如 年齡 隻能是整數,在schema可以直接定義一個整數類型
*** schema文法更加複雜,schema目前不能替代dtd
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>
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方法
使用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,在列印内容
使用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()
** 擷取标
使用dom4j查詢xml
* 解析是從上到下解析
* 查詢所有name元素裡面的值
* 查詢第一個name元素的值
* 擷取第二個name元素的值
使用dom4j查詢xml
* 解析是從上到下解析
* 查詢所有name元素裡面的值
* 查詢第一個name元素的值
* 擷取第二個name元素的值
7、使用dom4j實作添加操作
* 在第一個p1标簽末尾添加一個元素 <sex>nv</sex>
* 步驟
使用dom4j實作在特定位置添加元素
* 在第一個p1下面的age标簽之前添加 <school>ecit.edu.cn</schlool>
* 步驟
** 可以對得到document的操作和 回寫xml的操作,封裝成方法
** 也可以把傳遞的檔案路徑,封裝成一個常量
*** 好處:可以提高開發速度,可以送出代碼可維護性
- 比如想要修改檔案路徑(名稱),這個時候隻需要修改常量的值就可以了,其他代碼不需要做任何改變
使用dom4j實作修改節點的操作
* 修改第一個p1下面的age元素的值 <age>30</age>
* 步驟
使用dom4j實作删除節點的操作
* 删除第一個p1下面的<school>ecit</school>元素
* 步驟
使用dom4j擷取屬性的操作
* 擷取第一個p1裡面的屬性id1的值
* 步驟
//得到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")
* 步驟和代碼
//得到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);