一、XML简介
1.1什么是XML?
XML全称eXtendsible Markup Language,即可扩展的标记语言,与HTML语言有一定的相似之处,例如都是使用标签来定义,格式上有很多相同的地方,最大的区别就在于HTML中所定义的标签都是被预先定义好的,就像java中的关键字,例如< AA >< /AA >这对标签在HTML中是无效的,而XML别不同,它的标签可以完全由自己自定义,这就是二者最大的区别。
1.2XML有什么用?
1.可以用来保存数据
2.也可以用来做配置文件
3.数据传输载体
二、XML结构分析
2.1 文档声明
简单声明
version:解析这个xml文档的时候用什么版本的解析器解析
<? xml version="1.0" ?>
encoding
encoding:解析xml中的文字的时候用什么编码来翻译
<? xml version="1.0" encoding="gbk" ?>
standalone
no:该文档会依赖关联其他文档
yes:这是一个独立文档
<?xml version-"1.0" encoding="utf-8" standalone="no" ?>
2.2 Encoding 详解
- 在解析这个xml的时候,使用什么编码去解析。
- 解码:将文字或者数据以二进制的形式保存到机器中,文字和数据对应的二进制的翻译过程就是解码
- 默认文件保存的时候使用的编码是GBK,所以当xml文档出现乱码的时候有两种解决方法
1.让文档声明的encoding也是gbk或者gbk2312
2. 如果encoding是utf-8,那么保存文件的时候也要使用utf-8 - 保存文件的时候见到的ANSI对应的就是我们的本地编码GBK,为了通用,建议使用UTF-8的编码保存,以及encoding也是UTF-8
2.3元素定义
-
其实就是里面的标签,<>括起来的都叫元素,成对出现,如下
<stu></stu>
-
根元素:文档声明下来的第一个元素就叫做根元素,也就是根标签
-
标签里面可以嵌套标签
-
即是开始也是结束,一般配合属性来用
<age /> --就像是html中的 <img src=""/>
-
自定义标签命名规则:
1.名称可以含字母、数字、以及其他字符 2.名称不能以数字或者标点符号开始 3.名称不能以xml、XmlXML开始 4.名称不能包含空格 5.命名要尽量简单,做到见名知义
-
简单元素&复杂元素
简单元素:元素里面只包含了普通的文字 复杂元素:元素里面还可以嵌套其他的元素
-
元素属性的定义
定义在元素里面,<元素名称 属性名称="属性的值"></元素名称> <stus> <stu id="101"> <name>张三</name> <age>18</age> </stu> <stu id="102"> <name>李四</name> <name>王五</name> <age>18</age> </stu> </stus>
-
xml注释
格式:<!-- --> <!-- 这是一段xml注释示例 --> 注意:注释不可以在文档的第一行,必须要在文档声明的下面,虽然在浏览器上能正常显示但是在书写的时候会报错,在规则上也是错误的。
-
CDATA区
如果某段字符串里面有很多的字符,并且里面含有类是标签或者关键字这种文字,不想让xml的解析器去解析,那么可以把它定义为CDATA 区,格式如下: <![CDATA[]]> <des> <![CDATA[<a href="http://www.baidu.com">广州工商学院</a>]]> </des> 这样在这个xml被解析之后“广州工商学院”就会成为一个超链接。
-
非法字符
严格来讲,在xml中仅有"<"和&是非法的,省略号、引号、和大于号是合法的,但是替换为实体引用是一个好习惯 < ---- < & ----& 非法字符是不能被xml识别的,需要被替换成指定的编码才可以在页面中正常显示。
三、解析XML的技术
XML解析就是指获取元素里面的字符数据或者属性数据
3.1 XML的解析方式(面试常问)
解析方式其实有很多种,但是一般常用的有两种
1.DOM解析
2.SAX解析
针对者两种解析方式的API有:
jaxp ---由sun公司制定,比较繁琐
jdom---常用
dom4j---常用
3.2 dom4j的基本用法
//记得先导入dom4j所需要的jar包
element.element("stu"):返回该元素下的第一个stu元素
element.elements();返回该元素下的所有子元素
1.创建SaxReader对象
SAXReader reader=new SAXReader();
2.指定解析的xml源
Document document =reader.read(new File("src/xml/stus.xml"))
3.获取根元素
Element rootElement=document.getRootElement();
4.根据根元素获得子元素
rootElement.element("age")
SaxReader 创建好对象之后,通过read的方法将xml文档以树的形式读入内存,然后先获取根元素,再通过根元素获取想要的子元素,然后再用getName()和getText()获取元素的名字和值。
3.3 Dom4j 的 Xpath使用
dom4j里面支持Xpath的写法。 xpath其实是xml的路径语言,支持我们在解析xml的时候,能够快速的定位到具体的某一个元素。
1. 添加jar包依赖 jaxen-1.1-beta-6.jar
2. 在查找指定节点的时候,根据XPath语法规则来查找
3. 后续的代码与以前的解析代码一样。
------Xpath实例-----
<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
<book category="COOKING">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="CHILDREN">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="WEB">
<title lang="en">XQuery Kick Start</title>
<author>James McGovern</author>
<author>Per Bothner</author>
<author>Kurt Cagle</author>
<author>James Linn</author>
<author>Vaidyanathan Nagarajan</author>
<year>2003</year>
<price>49.99</price>
</book>
<book category="WEB">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
---使用XML DOM对象来加载xml文档,并使用 selectNodes() 函数从 XML 文档选取节点--
set xmlDoc=CreateObject("Microsoft.XMLDOM")
xmlDoc.async="false"
xmlDoc.load("books.xml")
xmlDoc.selectNodes(路径表达式)
------选取所有的 book 节点------
xmlDoc.selectNodes("/bookstore/book")
------选取所有价格高于 35 的 price 节点------
xmlDoc.selectNodes("/bookstore/book[price>35]/price")
四、XML约束
如上的xml文档, 属性的ID值可以被设置成一样的。 这在生活中是不可能出现的。 并且第二个学生的姓名有好几个。 一般也很少。那么怎么规定ID的值唯一, 或者是元素只能出现一次,不能出现多次? 甚至是规定里面只能出现具体的元素名字,这就需要我们对这个xml文档进行约束。
XML的约束有两种:一种是DTD约束,另一种是Schema约束
4.1 DTD约束
1.引用网络上的DTD约束
文档类型 跟标签名字 网络上的DTD dtd的名称 dtd的路径
<!DOCTYPE stus PUBLIC "//UNKNOWN/" "unknown.dtd">
2.引用本地的DTD
文档类型 根标签名字 引入本地DTD dtd的位置
<!DOCTYPE stu SYSTEM "stus.dtd">
3.直接在XML里面嵌入DTD约束规则
<!DOCTYPE stus [
<!ELEMENT stus (stu)>
<!ELEMENT stu (name,age)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
]>
<!ELEMENT stus(stu)>:约束了stus下面只有一个stu元素
<!ELEMENT stu(name,age)>约束了stu下面有两个有两个元素,name和age且顺序不能变
<!ELEMENT name(#PCDATA)>
<!ATTLIST stu id CDATA #IMPLIED>约束了stu有一个属性,该属性可有可无
元素的个数:
+---->一个或多个
*----->0个或者多个
?------>0个或者一个
属性声明拥使用下列语法:<!ATTLIST 元素名称 属性名称 属性类型 默认值>
属性的类型定义:
CDATA:属性是普通的文字
ID:属性的值必须唯一
例子----> <!ATTLIST student id CDATA #REQUIRED>
默认值:
#REQUIRED 属性值是必需的
#IMPLIED 属性不是必需的
#FIXED value
DTD约束实例
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE stu SYSTEM "stu.dtd"><!--引入本地DTD-->
<stu>
<student id="1">
<name>张三</name>
<course>C语言</course>
<score>88</score>
</student>
<student id="2">
<name>李四</name>
<course>C语言</course>
<score>3</score>
</student>
</stu>
------------以下是DTD文件---------------
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT stu (student+)> <!--+号表示stu里面有一个或者多个student对象-->
<!ELEMENT student (name, course, score)><!--这里定义的顺序是xml必须保持一致的-->
<!ATTLIST student id CDATA #REQUIRED>
<!ELEMENT name (#PCDATA)>
<!ELEMENT course (#PCDATA)>
<!ELEMENT score (#PCDATA)>
4.2 Schema约束
它其实就是一个xml,使用xml的语法规则,xml解析器解析起来比较方便,是为了代替DTD而出现的,但是由于Schema约束文本内容比DTD多,所以没有真正意义上的代替
约束文档:
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.itheima.com/teacher"
elementFormDefault="qualified">
<element name="teachers">
<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>
请求头解析:
<?xml version="1.0" encoding="UTF-8"?>
<!-- xmlns:xsi : 这里必须是这样的写法,也就是这个值已经固定了。
xmlns : 这里是名称空间,也固定了,写的是schema里面的顶部目标名称空间 xsi:schemaLocation : 有两段: 前半段是名称空间,也是目标空间的值 , 后面是约束文档的路径。
4.3 命名空间的作用
一个xml如果想指定它的约束规则, 假设使用的是DTD ,那么这个xml只能指定一个DTD , 不能指定多个DTD 。 但是如果一个xml的约束是定义在schema里面,并且是多个schema,那么是可以的。简单的说: 一个xml 可以引用多个schema约束。 但是只能引用一个DTD约束。
名称空间的作用就是在 写元素的时候,可以指定该元素使用的是哪一套约束规则。 默认情况下 ,如果只有一套规则,那么都可以这么写
<name>张三</name>
<aa:name></aa:name>
<bb:name></bb:name>