前面几讲我们学习了DTD的内容,这一讲我们来开始学习一下Schema。如果将DTD比作Java中的数组的话,那么Shema就相当于Java中的集合。所以Schema是一种更加强大的约束XML元素和属性的工具。
Schema(模式):其作用与dtd一样,也是用于验证XML文档的有效性,只不过它提供了比dtd更强大的功能和更细粒度的数据类型,另外Schema还可以自定义数据类型。此外,Schema也是一个XML文件,而dtd则不是。
1. 学习目标
理解Schema的数据类型
理解Schema的元素类型
理解验证与约束
2. 什么是Schema
XML Schema 是用一套预先规定的XML元素和属性创建的,这些元素和属性定义了XML文档的结构和内容模式。
XML Schema 规定XML文档实例的结构和每个元素/属性的数据类型。如下图所示
3. 我们来比较一下同样的XML,用DTD、XML、Schema三种不同的方式去验证会是什么样的。
1) XML
<书本>
<名称>书剑恩仇录</名称>
<作者>金庸</作者>
</书本>
2) DTD
<!ELEMENT 书本 (名称,作者)>
<!ELEMENT 名称 (#PCDATA)>
<!ELEMENT 作者 (#PCDATA)>
3) Schema
<element name=“书本” type=“书本类型”/>
<complexType name=“书本类型”>
<element name=“名称” type=“string”/>
<element name=“作者” type=“string”/>
</complexType>
4. 为什么要用Schema
1) DTD 的局限性
DTD不遵守XML语法(写XML文档实例时候用一种语法,写DTD的时候用另外一种语法)
DTD数据类型有限(与数据库数据类型不一致)
DTD不可扩展
DTD不支持命名空间(命名冲突)
2) Schema的新特性
Schema基于XML语法
Schema可以用能处理XML文档的工具处理
Schema大大扩充了数据类型,可以自定义数据类型
Schema支持元素的继承—Object-Oriented’
Schema支持属性组
5. 下面我来先举一个例子看下Schema是如何使用的?如何在XMLSpy里面编写一个Schema,如何去利用Shema去验证这个XML,后面再详细对其进行剖析。
1) 在XMLSpy中新建一个Schema文件,内容如下所示:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:element name="书本" type="书本类型"/> <xs:complexType name="书本类型"> <xs:sequence> <xs:element name="名称" type="xs:string"/> <xs:element name="作者" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:schema>
2) 在新建一个XML文件,同时在弹出的对话框中指定好上述Schema文档的路径,如下图所示,这样就可以用直接指定了用上述Schema文档来约束要新建的XML文件了
<?xml version="1.0" encoding="UTF-8"?> <书本 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="C:\Users\xukunhui\Desktop\workspace_xml\mySchema.xsd"> <名称>书剑恩仇录</名称> <作者>金庸</作者> </书本>如上述两个步骤所示,建立Schema流程基本上就是这样
6. Schema的文档结构[说明] xmlns:xs="http://www.w3.org/2001/XMLSchema" 表示:命名空间
1) 用于构造schema的元素和数据类型来自http://www.w3.org/2001/XMLSchema命名空间,这个命名空间URL是不能改的,这是XML内置的,固定的,我们Schema所有的内置和扩展的元素类型全都是来自这个命名空间
2) 本schema定义的元素和数据类型属于http://mynamespace/myschema命名空间,这是我们自定义的数据类型的,这些类型是位于这个命名空间下面,所以这个命名空间的URL可以改的。
3) 注意在一个XML文档里面,可能存在多个命名空间
4)所有的schema文档,其根元素必须为schema。
5) 上面的命名空间xs是可以换其他字符代替的,而且在不同的IDE环境下,这个命名空间它有几种写法的,比如再XMLSpy中一般使用xs,而再Eclipse中一般是xsd来表示的。
7. Schema的数据类型
1) 简单类型
(1) 内置的数据类型(built-in data types)
基本的数据类型
扩展的数据类型
(2) 用户自定义数据类型(通过simpleType定义)
2) 复杂类型(通过complexType定义)
[如上面程序中的 "书本类型" 就是一个复杂类型,就是说书本类型是我自己定义的,不是Schema自带的,我是靠它里面现有的元素,构造出来一个新的类型,就好比如Java里面提供的类,构造出我们自己的类一样。所以用Schema可以构造自己需要的很多我们需要的数据类型]
8. Schema数据类型
1) 基本数据类型
2) 扩展的数据类型
3) 数据类型的特性,类似与Java中的属性的特点。
[说明]Schema现在已经越来越多被人使用了,比如webserver开发里面servelet 2.3之前XML都是用DTD验证,从2.3之后就变成Schema来验证了,同样Sprint 在1.2之前也是用DTD来验证的,在1.2之后就是用Schema来验证了,包括2.0,2.5,3.0全是用 Schema来验证了
9. Schema的元素类型 有14个
Schema元素,任何一个XML Schema文档,它的根元素都是Schema。
作用:包含已经定义的schema
用法:<xs:schema>
属性:
xmlns [关键是这个元素]
targetNamespace [不是很关键]
10. element 元素
1) 作用:声明一个元素
2) 属性:name, type, ref, minOccurs, maxOccurs, substitutionGroup, fixed, default等
3) 示例:
<xs:element name="cat" type="xs:string"/>
<xs:element name="dog" type="xs:string"/>
<xs:element name="pets">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element ref="cat"/>
<xs:element ref="dog"/>
</xs:sequence>
</xs:complexType>
</xs:element>
[说明]:注意我们在DTD里面定义元素的时候都是用大写的,而在schema中元素是小写的,它和Java中的属性和方法是一样的,后面如果跟多个单词,首个单词小写后面单词首字母大写。
在我们之前学习的过程中,知道XML文档是用DTD来验证它的有效性,但是现在我们有了Schema,Schema它本身就是一个XML文档,那Schema会有谁去验证它的有效性呢?答案就是DTD,因为DTD是验证的本源。没有什么东西会再去验证DTD的有效性。
我们可以去网址:http://www.w3.org/2001/XMLSchema 查询Schema的验证DTD,这是一个万维网的官方网址,这就是为什么上面说的以上这个地址是不能换的,因为这样就就可以指定好用这个地址里面的信息去验证了。
[说明]:在以上程序中我们可以发现:
<xs:element name="cat" type="xs:string"/>
<xs:element name="dog" type="xs:string"/>
其对应的XML文件可以写成
<cat>hello</cat>
<dog>world</dog>
然后是这复杂的数据类型,这个数据类型是引用上面的两个元素结合而来的。
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element ref="cat"/>
<xs:element ref="dog"/>
</xs:sequence>
</xs:complexType>注意:在这一块中,complexType 它只定义了类型,元素还没定义好,所以它是没法直接用的,就好比如Java中它只定义好了类,但是还没定义好这个类的实例。定义好数据类型之后就可以声明好这个元素是属于这种数据类型的。 当我在这个数据类型中定义好了某一个元素之后,我们就可以使用这个元素了。
sequence表示cat 和 dog 是按顺序来的。
4) 下面我们来演示一下上面的Schema是如何使用的
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <!-- 注意 xs:element name="cat" type="xs:string"中必须加上xs:因为它们都是在命名空间下面的 --> <xs:element name="cat" type="xs:string"/> <xs:element name="dog" type="xs:string"/> <!-- 定义好数据类型之后就可以声明好这个元素是属于这种数据类型的。当我在这个数据类型中定义好了某一个元素之后,我们就可以使用这个元素了。--> <xs:complexType name="myType"> <xs:sequence> <xs:element ref="cat"/> <xs:element ref="dog"/> </xs:sequence> </xs:complexType> <!--表示定义了一个元素pets,它的数据类型是myType,所以perts这个元素里面有两个子元素,分别是上面的cat和dog--> <xs:element name="pets" type="myType"/> </xs:schema>
再定义其对应的xml文档
<?xml version="1.0" encoding="UTF-8"?> <pets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="pets.xsd"> <cat>hello</cat> <dog>world</dog> </pets>
[说明]:这边需要注意的是凡是在Schema里面定义的element元素,就是表示在XML中是可以直接用的,而定义的类型则不能被XML所用,类型是一种抽象的概念,元素才是具体的概念,只有定义好元素才能在XML中被使用。