XML
1.
概念
XML:Extendsible Markup Language
可扩展标记语言
1.
可扩展:
标签都是自定义的
2.
功能:
1.
配置文件
2.
在网络中传输
3.
与
HTML
的区别:
1. XML
标签是自定义的,
HTML
标签是预定义的。
2. XML
的语法严格,
HTML
语法松散
3. XML
是存储数据的,
HTML
是展示数据
2.
语法
1.
语法:
1. XML
文档的后缀:
.xml
2. XML
文档的第一行必须是文档声明:
<?xml version='1.0'?>
3. XML
文档中有且仅有一个根标签
4.
属性值必须使用引号(单双引号均可)引起来
5.
标签必须正确关闭
6. XML
标签区分大小写
案例:
新建一个
.xml
文件,将下列内容写入该文件中,使用浏览器打开 ,只要不报错,就证明
XML
格式正确。
<?xml version='1.0'?>
<users>
<user
id
=
'1'
>
<name>
比尔盖茨
</name>
<age>
67
</age>
<gender>
male
</gender>
</user>
<user
id
=
'2'
>
<name>
乔布斯
</name>
<age>
64
</age>
<gender>
male
</gender>
</user>
</users>
2.
组成
1.
文档声明
格式
:
<?xml
属性列表
?>
属性列表:
version :
版本号
encoding :
编码格式。告知 解析引擎当前文档使用的字符集,默认值:
ISO-8859-1
。
用来校验文本
实际编码集是否与告知编码集相符
standalone :
是否独立
取值:
yes
:不依赖其他文件
no
:依赖其他文件
2.
指令
:与
css
结合使用控制
XML
样式的。现在已经不用了。
3.
标签
:自定义标签
规则:
1.
名称可以包含字母,数字以及其他字符
2.
名称不能以数字或者标点符号开始
3.
名称不能以 字母组合
xml
(任何大小写组合都不行,
XML
,
Xml
等)开始
4.
名称不能包含空格
4.
属性
规则
1.
以键值对的形式存在
2.
属性必须用引号引起来
3. id
属性值必须唯一
5.
文本
注意
1.
文本中 包含
<
,
>
,
&
必须使用转译字符:
<
=
<
;
,
&
=
&
;
,
>
=
>
;
2. CDATA
区:该区域中的数据会被原样输出,不必使用转译字符
格式:
<![CDATA[
内容
]]>
3.
约束
3.1
概述:
规定
xml
文档的书写规范
2.
学习要求:
能够在
xml
中引入约束文档
能够大致读懂约束文档
3.
约束图解:
<![CDATA[ if(a>b && a<100) ]]>
4.
分类
DTD
:简单的约束 技术
Schema:
复杂的约束技术
3.2 DTD
引入:
内部
DTD:
将约束规则定义在
XML
文档中(写完外部再写内部即可)
外部
DTD
:将约束的规则定义在外部
DTD
中
本地:
<!DOCTYPE
根标签名
SYSTEM "DTD
文件位置
">
<?xml version="1.0" encoding="utf-8" ?>
<!--<!DOCTYPE students SYSTEM "\dtd\Student.dtd">-->
<!DOCTYPE students [
<!--students
标签,它内部可以包含
0-n
个
student
标签
-->
<!ELEMENT students (student*)>
<!--student
标签,它内部包含
name,age,sex
三个标签
,
顺序必须按照规定顺序,并且只
能出现一次
-->
<!ELEMENT student (name,age,sex)>
<!--name
标签
#pcdata
代表
String
类型
-->
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT sex (#PCDATA)>
<!--
定义属性:
student
标签中
number:
属性名
ID
:唯一
#required:
必须的
--
>
<!ATTLIST student number ID #REQUIRED>
]>
<students>
<student
number
=
"s001"
>
<name>
刘德华
</name>
<age>
25
</age>
<sex>
男
</sex>
</student>
</students>
网络
:
<!DOCTYPE
跟标签名
PUBLIC "DTD
文件名
" "DTD
文件位置(
URL
)
"
先写
DTD
约束
再写
XML
,并引入
DTD
通过上述案例,我们不难发现
DTD
的弊端:
无法对属性内容进行限定
。比如我们无法去限定
age
必须在
0~100
之间。
3.3 Schema
Schema
文档要求能够读懂,可以做简单修改即可。
Student.xsd
<!--students
标签,它内部可以包含
0-n
个
student
标签
-->
<!ELEMENT
students
(
student
*
)>
<!--student
标签,它内部包含
name,age,sex
三个标签
,
顺序必须按照规定顺序,并且只能出现一
次
-->
<!ELEMENT
student
(
name
,
age
,
sex
)>
<!--name
标签
#pcdata
代表
String
类型
-->
<!ELEMENT
name
(
#PCDATA
)>
<!ELEMENT
age
(
#PCDATA
)>
<!ELEMENT
sex
(
#PCDATA
)>
<!--
定义属性:
student
标签中
number:
属性名
ID
:唯一
#required:
必须的
-->
<!ATTLIST
student number ID
#REQUIRED
>
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE students SYSTEM "\dtd\Student.dtd">
<students>
<student
number
=
"s001"
>
<name>
刘德华
</name>
<age>
25
</age>
<sex>
男
</sex>
</student>
</students>
<?xml version="1.0"?>
<xsd:schema
xmlns
=
"http://www.wdzl.cn/xml"
xmlns:xsd
=
"http://www.w3.org/2001/XMLSchema"
targetNamespace
=
"http://www.wdzl.cn/xml"
elementFormDefault
=
"qualified"
>
<xsd:element
name
=
"students"
type
=
"studentsType"
/>
<xsd:complexType
name
=
"studentsType"
>
<xsd:sequence>
<xsd:element
name
=
"student"
type
=
"studentType"
minOccurs
=
"0"
maxOccurs
=
"unbounded"
/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType
name
=
"studentType"
>
<xsd:sequence>
<xsd:element
name
=
"name"
type
=
"xsd:string"
/>
<xsd:element
name
=
"age"
type
=
"ageType"
/>
<xsd:element
name
=
"sex"
type
=
"sexType"
/>
</xsd:sequence>
<xsd:attribute
name
=
"number"
type
=
"numberType"
use
=
"required"
/>
</xsd:complexType>
<xsd:simpleType
name
=
"sexType"
>
<xsd:restriction
base
=
"xsd:string"
>
<xsd:enumeration
value
=
"male"
/>
<xsd:enumeration
value
=
"female"
/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType
name
=
"ageType"
>
<xsd:restriction
base
=
"xsd:integer"
>
<xsd:minInclusive
value
=
"0"
/>
<xsd:maxInclusive
value
=
"256"
/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType
name
=
"numberType"
>
<xsd:restriction
base
=
"xsd:string"
>
<xsd:pattern
value
=
"IT_\d{3}"
/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
头信息:
主体部分:
Student.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!--
1. xml
的根元素
2.
引入
xsi
前缀
-
固定格式:
http://www.w3.org/2001/XMLSchema-instance
3.
引入
xsd
文件命名空间:
xsi:schemaLocation="http://www.wdzl.cn/xml student.xsd
*http://www.wdzl.cn/xml
:命名空间
*student.xsd
:文件存储路径
4.
为每一个
xsd
约束 声明一个前缀,作为标识
*
因为一个
xml
中可能有多个约束文档,前缀的作用用于区分同名标签属于哪一个
xsd
的情况
*
声明格式:
<xmlns:
标签名
=“
命名空间
”>
4.
解析
4.1
常见
XML
操作
1.
解析(读取)
:将文档中的数据读取到内存中
2.
写入(持久化)
:将内存中的数据保存到
xml
文档中。不常用
4.2
解析
XML
的方式
1.
DOM
:将标记语言文档一次性加载进内存,在内存中形成一颗
dom
树
优点:
操作简单,可以对文档进行
CRUD
的所有操作
缺点:
占内存,不适用移动和嵌入式设备。
2.
SAX
:逐行读取,基于事件驱动的解析方式
*
使用格式:
<a:name></a:name>,
不写使用默认空前缀
-->
<a:students
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
=
"http://www.wdzl.cn/xml student.xsd"
xmlns:a
=
"http://www.wdzl.cn/xml"
>
<a:student
number
=
"wdzl_0001"
>
<a:name>
周杰
a:
伦
</a:name>
<a:age>
18
</a:age>
<a:sex>
female
</a:sex>
</a:student>
<a:student
number
=
"wdzl_0002"
>
<a:name>
呵呵
</name>
<a:age>
17
</age>
<a:sex>
male
</sex>
</a:student>
<a:/students>
Sun
公司在
JDK5
版本对
DOM
解析技术的升级,并命名为
SAX
(
Simple API for XML
)。
SAX
是逐行
读取
xml
文件,不会创建大量的
DOM
对象,所以在内存使用和性能上,都优于
DOM
解析。
3.
第三方的解析
jdom
:在
dom
基础上进行封装。
dom4j
:是在
jdom
上进行了在封装。
pull
主要用在
Android
手机开发。它与
SAX
非常类似,都是事件驱动方式解析
xml
文件。
3. dom4j
解析技术
-
重点
3.1 dom4j
类库的使用
由于
dom4j
它不是
sun
公司的技术,而属于第三方公司的技术,需要我们配置依赖
jar
包。
3.2 dom4j
解析案例
1.
准备
xml
解析用例
2.
准备对应的
Book
类
<?xml version="1.0" encoding="UTF-8" ?>
<books>
<book
bid
=
"BID123456"
>
<name>
Java
葵花宝典
</name>
<price>
20.50
</price>
<author>
詹姆斯高斯林
</author>
</book>
<book
bid
=
"BID223456"
>
<name>
JavaSE
入门宝典
</name>
<price>
29.90
</price>
<author>
比尔盖茨
</author>
</book>
</books>
public class
Book
{
private
String
bid
;
private
String
name
;
private
String
price
;
private
String
author
;
public
Book
() {
}
public
Book
(
String
bid
,
String
name
,
String
price
,
String
author
) {
this
.
bid
=
bid
;
this
.
name
=
name
;
this
.
price
=
price
;
this
.
author
=
author
;
}
public
String
getBid
() {
return
bid
;
}
public
void
setBid
(
String
bid
) {
this
.
bid
=
bid
;
}
public
String
getName
() {
return
name
;
}
public
void
setName
(
String
name
) {
this
.
name
=
name
;
}
public
String
getPrice
() {
return
price
;
}
public
void
setPrice
(
String
price
) {
this
.
price
=
price
;
}
public
String
getAuthor
() {
return
author
;
}
public
void
setAuthor
(
String
author
) {
this
.
author
=
author
;
}
@Override
public
String
toString
() {
return
"Book{"
+
"bid='"
+
bid
+
'\''
+
", name='"
+
name
+
'\''
+
", price="
+
price
+
", author='"
+
author
+
'\''
+
'}'
;
}
}
3.
新建
jar
包,并将
jar
添加到项目中
4.
使用
dom4j
读取
xml
文件
@Test
public
void
test
()
throws
DocumentException
{
//
创建一个
SAXReader
输入流,读取
xml
文件,生成
Document
对象
SAXReader saxReader
=
new
SAXReader
();
Document document
=
saxReader
.
read
(
"xml\\book.xml"
);
System
.
out
.
println
(
document
);
}
结果:
5.
通过
Document
对象获取
xml
数据包装成实体类
//
读取
books.xml
文件生成
book
类
@Test
public
void
test2
()
throws
DocumentException
{
//1.
读取
book.xml
文件
SAXReader saxReader
=
new
SAXReader
();
Document document
=
saxReader
.
read
(
"xml\\book.xml"
);
//2.
通过
Document
对象获取根元素
Element rootElement
=
document
.
getRootElement
();
//3.
通过跟元素获取
book
标签对象
//element()
和
elements()
都可以获取子元素,我们只需要根据子元素的多少选择用哪一个
即可
List
<
Element
>
books
=
rootElement
.
elements
(
"book"
);
//4.
遍历,处理每个标签转换为
Book
类
for
(
Element book
:
books
) {
//asXML():
将标签对象,转换为标签对应的字符串
// System.out.println(book.asXML());
//
单独拿出
name
标签
Element nameElement
=
book
.
element
(
"name"
);
//System.out.println(nameElement.asXML());
// getText()
获取标签中的文本内容
String
nameText
=
nameElement
.
getText
();
//System.out.println(nameText);
//
直接获取指定标签名的文本内容
String
priceText
=
book
.
elementText
(
"price"
);
String
authorText
=
book
.
elementText
(
"author"
);
//System.out.println(nameText+"--"+priceText+"--"+authorText);
//
获取属性
String
bid
=
book
.
attributeValue
(
"bid"
);
// System.out.println(bid+"--"+nameText+"--"+priceText+"--
"+authorText);
System
.
out
.
println
(
new
Book
(
bid
,
nameText
,
priceText
,
authorText
));
}
}