XML小筆記
XML內容
XML解析
其實就是獲取元素裡面的字元資料或者屬性資料
解析方式
有很多種,但是常用的有兩種
- DOM
- SAX
DOM:document object model 把整個xml全部讀到記憶體中,形成樹狀結構,整個文件稱之為documet物件,屬性對應attribute物件,所有的元素節點對應element物件,文字稱之為text 物件,以上所有物件都可以稱之為Node節點。如果xml特別大,那麼將會造成記憶體溢位,可以對文件進行增刪操作。
SAX: Simple API for Xml 基於事件驅動,讀取一行,解析一行。不會造成記憶體溢位,不可以進行增刪,只能查詢
針對這兩種解析方式的API
- jaxp sum公司,比較繁瑣
- jdom
- dom4j 使用比較廣泛
dom4j基本用法
前提:下載dom4j的包
1.建立SAXReader物件
2.指定解析的xml
3.獲取根元素
4.根據根元素獲取子元素或者下面的子孫元素
public class MainTest{
public static void main(String[] args){
try{
//1.建立sax讀取物件
SAXReader reader = new SAXReader();
//2.指定解析的xml源
Document document = reader.read(new File("xxx"));
//3.得到元素
//根元素
Element rootElement = document.getRootElement();
//獲取根元素下面的子元素age
System.out.println(rootElement.element("stu").element("age").getText());
//獲取根元素下面的所有子元素
List<Element> elements = rootElement.elements();
//遍歷獲取子孫元素
for(Element e:elements){
String name = e.element("name").getText();
}
}catch(Exception e){
e.PrintStackTrace();
}
}
}
xpath的用法
dom4j裡面支援Xpath的寫法
xpath其實是xml的路徑語言,支援我們在解析xml的時候,能夠快速定位到具體的某一個元素
1.新增jar包依賴
jaxen-1.1-beta-6.jar
2.在查詢指定節點的時候,根據xpath語法規則來查詢
3.後續的程式碼與以前的解析程式碼一樣
//根元素
Element rootElement = document.getRootElement();
//要想使用Xpath,還得新增支援的jar 獲取的是第一個元素
//獲取所有名字為name的元素中的第一個
Element nameElement = (Element)rootElement.selectSingleNode("//name");
System.out.println(nameElement.getText());
//獲取文件裡面的所有name元素
List<Element> list = rootElement.selectNodes("//name");
//遍歷輸出text
for(Element e:elements){
System.out.println(e.getText());
}
XML約束
有時候XML需要某些要求,比如說ID唯一,元素只能出現一次等等,這就需要對XML新增XML約束了
約束主要有以下兩類:
-
DTD
語法自成一派,早期就出現的,可讀性比較差
-
Schema
其實就是一個XML,使用XML語法規則,XML解析器解析起來比較方便,是為了代替DT,但是Schema約束文字內容比DTD的內容還要多,所以目前也沒有真正意義上替代DTD
DTD基本用法
DTD的寫法
<!-- 一共有四個元素 -->
<!-- stus元素中有stu,但是隻有一個 -->
<!-- 元素的個數
+ 一個或多個
* 零個或多個
? 零個或一個
沒有 只有一個 -->
<!ELEMENT stus(stu)+>
<!-- stu元素中有name和age,而且name必須在age前面 -->
<!ELEMENT stu(name,age)>
<!-- name元素中是可解析字元文字 -->
<!ELEMENT name(#PCDATA)>
<!-- age元素中是可解析字元文字 -->
<!ELEMENT age(#PCDATA)>
<!-- stu有一個屬性id 文字型別 該屬性可有可無 -->
<!-- 如果屬性是必需的,用#REQUIRED
如果屬性是固定的,用#FIXED values
如果要給它設一個預設值,則直接在此位置輸入值就行 -->
<!ATTLIST stu id CDATA #IMPLIED>
在xml中引入DTD,有三種途徑
1.引入網路中的DTD
<?xml version="1.0" encoding="UTF-8"?>
<!-- 引入DTD來約束這個xml -->
<!-- 1.引入網路上的DTD
DOCTYPE:文件型別
stus:根標籤名字
PUBLIC:指網路上的DTD
"//UNKNOWN/":DTD名稱
"unknown.dtd":網路上的DTD路徑-->
<!DOCTYPE stus PBULIC "//UNKNOWN/" "unknown.dtd">
2.第二種,引入本地的DTD
<!-- 2.引入本地的DTD
DOCTYPE:文件型別
stus:根標籤名字
SYSTEM:指本地的DTD
"unknown.dtd":本地的DTD路徑-->
<!DOCTYPE stus SYSTEM "stus.dtd">
3.第三種,直接在xml內嵌DTD
<!DOCTYPE stus[
<!ELEMENT stus(stu)>
<!ELEMENT stu(name,age)>
<!ELEMENT name(#PCDATA)>
<!ELEMENT age(#PCDATA)>
]>
Schema基本用法
Schema的寫法
<?xml version="1.0" encoding="UTF-8">
<!-- xmlns:xml namespeace 名稱空間/名稱空間
targetNamespeace: 目標名稱空間,下面定義的那些元素都與這個名稱空間繫結上
elementFormDefault: 元素的格式化情況 -->
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespeace="http://www.example.org/teacher"
elementFormDefault="qualified">
<!-- 這是一個複雜元素-->
<element name="teachers"></element>
<complexType>
<sequence maxOccurs="unbounded">
<!-- 這是一個複雜元素 數量為無限大-->
<element name="teacher">
<complexType>
<sequence>
<!-- 以下是兩個簡單元素-->
<element name="name" type="String"></element>
<element name="age" type="int"></element>
<sequence>
</complexType>
</element>
<sequence>
</complexType>
</element>
</schema>
schema的引入
<?xml version="1.0" encoding="UTF-8"?>
<!-- xmlns:xsi :這裡必須是這樣的寫法,也就是這個值已經固定了
xmlns :這裡是名稱控,也固定了,寫的是schema裡面的頂部目標名稱空間
xsi:schemaLocation :有兩段,前半段是名稱空間,也是目標空間的值,後半段是約束文件的路徑-->
<teachers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.example.org/teacher"
xsi:schemaLocation="http://www.example.org/teacher teacher.xsd"
>
<teacher>
<name>zhangsan</name>
<age>18</age>
</teacher>
<teacher>
<name>lisi</name>
<age>15</age>
</teacher>
</teachers>
名稱空間的作用
一個xml可以引用多個schema約束,但是隻能引用一個DTD約束
下面是引用多個schema約束的情況
<teachers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:bb="http://www.example.org/teacher"
xmlns:aa="http://www.example.org/teacher"
xsi:schemaLocation="http://www.example.org/teacher teacher.xsd"
>
<teacher>
<aa:name>zhangsan</name>
<age>18</age>
</teacher>
<teacher>
<aa:name>lisi</name>
<age>15</age>
</teacher>
</teachers>