XML数据结构——Schema技术
一、XML Schema简介
1. 什么是XML Schema?
XML Schema 的作用是定义 XML 文档的合法构建模块,类似 DTD。
XML Schema 可描述 XML 文档的结构。
XML Schema 语言也可作为 XSD(XML Schema Definition)来被引用。
Ø 定义可出现在文档中的元素
Ø 定义可出现在文档中的属性
Ø 定义哪个元素是子元素
Ø 定义子元素的次序
Ø 定义子元素的数目
Ø 定义元素是否为空,或者是否可包含文本
Ø 定义元素和属性的数据类型
Ø 定义元素和属性的默认值以及固定值
2. 为什么要使用XML Schema?
XML Schema 比DTD更强大
XML Schema 最重要的能力之一就是对数据类型的支持。
通过对数据类型的支持:
² 可更容易地描述允许的文档内容
² 可更容易地验证数据的正确性
² 可更容易地与来自数据库的数据一并工作
² 可更容易地定义数据约束(data facets)
² 可更容易地定义数据模型(或称数据格式)
² 可更容易地在不同的数据类型间转换数据
XML Schema 使用 XML 语法
XML Schema 可保护数据通信
XML Schema 可扩展
² 在其他 Schema 中重复使用您的 Schema
² 创建由标准类型衍生而来的您自己的数据类型
² 在相同的文档中引用多重的 Schema
DTD与Schema比较:
DTD比较适合下面的情形:
① 文件是叙述性的,并有混合内容
② 需要约束标记之间的关系,特别是子标记的顺序关系,而不是标记本身的文字内容
③ 需要使用实体
④ Xml文件的使用者对使用的DTD达成一致
XML Schema比较适合下面的情形:
① 需要定义数据内容,以便约束标记的文本内容的结构
② 标记的子标记的顺序并不重要,重要的是其数量
③ 标记约束不限于父子关系,也可以是祖先及子孙关系
④ 跨越多个文件,名称空间前缀不一致
3. 如何使用Schema?
|
XML文件 |
DTD文件 |
|
Schema文件 |
note 元素是一个复合类型,因为它包含其他的子元素。其他元素 (to, from,heading, body) 是简易类型,因为它们没有包含其他元素。
在调用方式上也不一样:
对DTD的引用 |
|
对Schema的引用 |
二、XML中的命名空间 Namespace
1. 为什么要使用命名空间——避免两个元素名冲突
XML的元素名不是固定的,当两个不同的文档描述两个不同类型的元素的时候,就会发生命名冲突:
<dove>德芙</dove>
<dove>多芬</dove>
2. 使用URL作为XML的命名空间
<f:Schema xmls:f=” http://www.w3.org/2001/XMLSchema”>
schema 中用到的元素和数据类型来自命名空间"http://www.w3.org/2001/XMLSchema"。同时它还规定了来自命名空间 "http://www.w3.org/2001/XMLSchema" 的元素和数据类型应该使用前缀 f:
三、Schema 的定义
1. 一个简单的schema
<?xml version="1.0" encoding="utf-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <!--nonNegativeInteger表示非负整数--> <xs:element name="school" type="xs:nonNegativeInteger"></xs:element> </xs:schema> |
创建schema文件的两种方式:
方法一:创建一个xml文件,另存为xsd文件
方法二:直接创建
调用一个没有设置命名空间的xsd文件:
<?xml version="1.0" encoding="utf-8"?> <bookid x:noNamespaceSchemaLocation="test1.xsd" xmlns:x="http://www.w3.org/2001/XMLSchema-instance" >2000</bookid> |
2. Schema中的数据类型
(1) 基本数据类型
整数 int ,long ,integer,short,nonNegativeiInteger(无符号整型)
小数 decimal,float, double
实数
时间 datetime ,time,date
布尔型 boolean
字符串
(2) 自定义类型
<x:element name="goods" type="goodstype"> </x:element> <x:simpleType name="goodstype"> <x:restriction base="x:int"> <x:minExclusive value="1"></x:minExclusive> <x:maxInclusive value="10"></x:maxInclusive> </x:restriction> </x:simpleType> |
代码解析:
创建了一个简单类型goodstype,它是从int类型集成过来的,minExclusive和maxInclusive定义了它的最小值和最大值,最后定义goods元素的类型是goodstype.
使用restriction我们可以限制只能接受一定数值或者只能接受一定文字。
四、简单的类型
1. 简易元素
简易元素指那些仅包含文本的元素。它不会包含任何其他的元素或属性。
定义简易元素的语法:
<xs:elementname="xxx" type="yyy"/>
此处 xxx 指元素的名称,yyy 指元素的数据类型。XML Schema 拥有很多内建的数据类型。
最常用的类型是:
xs:string
xs:decimal
xs:integer
xs:boolean
xs:date
xs:time
例子:
这是一些 XML 元素:
<lastname>Smith</lastname>
<age>28</age>
<dateborn>1980-03-27</dateborn>
这是相应的简易元素定义:
<xs:elementname="lastname" type="xs:string"/>
<xs:element name="age"type="xs:integer"/>
<xs:elementname="dateborn" type="xs:date"/>
简易元素的默认值和固定值
简易元素可拥有指定的默认值或固定值。
当没有其他的值被规定时,默认值就会自动分配给元素。
在下面的例子中,缺省值是 "red":
<xs:elementname="color" type="xs:string" default="red"/>
固定值同样会自动分配给元素,并且您无法规定另外一个值。
在下面的例子中,固定值是 "red":
<xs:elementname="color" type="xs:string" fixed="red"/>
2. XSD 属性
1) 所有的属性均作为简易类型来声明。
简易元素无法拥有属性。假如某个元素拥有属性,它就会被当作某种复合类型。但是属性本身总是作为简易类型被声明的。
定义属性的语法是:
<xs:attributename="xxx" type="yyy"/>
在此处,xxx 指属性名称,yyy 则规定属性的数据类型。XML Schema 拥有很多内建的数据类型。
实例
这是带有属性的 XML 元素:
<lastnamelang="EN">Smith</lastname>
这是对应的属性定义:
<xs:attribute name="lang"type="xs:string"/>
2) 属性的默认值和固定值
属性可拥有指定的默认值或固定值。
当没有其他的值被规定时,默认值就会自动分配给元素。
在下面的例子中,缺省值是 "EN":
<xs:attributename="lang" type="xs:string" default="EN"/>
固定值同样会自动分配给元素,并且您无法规定另外的值。
在下面的例子中,固定值是 "EN":
<xs:attributename="lang" type="xs:string" fixed="EN"/>
3) 可选的和必需的属性
在缺省的情况下,属性是可选的。如需规定属性为必选,请使用 "use" 属性:
<xs:attribute name="lang"type="xs:string" use="required"/>
3. XSD 限定
1) 对值的限定
下面的例子定义了带有一个限定且名为 "age" 的元素。age 的值不能低于 0 或者高于 120:
<xs:elementname="age">
<xs:simpleType>
<xs:restrictionbase="xs:integer">
<xs:minInclusivevalue="0"/>
<xs:maxInclusivevalue="120"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
2) 对一组值的限定
如需把 XML 元素的内容限制为一组可接受的值,我们要使用枚举约束(enumeration constraint)。
下面的例子定义了带有一个限定的名为 "car" 的元素。可接受的值只有:Audi, Golf, BMW:
<xs:elementname="car">
<xs:simpleType>
<xs:restrictionbase="xs:string">
<xs:enumerationvalue="Audi"/>
<xs:enumerationvalue="Golf"/>
<xs:enumerationvalue="BMW"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
上面的例子也可以被写为:
<xs:elementname="car" type="carType"/>
<xs:simpleTypename="carType">
<xs:restrictionbase="xs:string">
<xs:enumerationvalue="Audi"/>
<xs:enumerationvalue="Golf"/>
<xs:enumerationvalue="BMW"/>
</xs:restriction>
</xs:simpleType>
注释:在这种情况下,类型"carType" 可被其他元素使用,因为它不是 "car" 元素的组成部分。
3) 对一系列值的限定
如需把 XML 元素的内容限制定义为一系列可使用的数字或字母,我们要使用模式约束(pattern constraint)。
下面的例子定义了带有一个限定的名为 "letter" 的元素。可接受的值只有小写字母 a - z 其中的一个:
<xs:elementname="letter">
<xs:simpleType>
<xs:restrictionbase="xs:string">
<xs:pattern value="[a-z]"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
下一个例子定义了带有一个限定的名为 "initials" 的元素。可接受的值是大写字母 A - Z 其中的三个:
<xs:elementname="initials">
<xs:simpleType>
<xs:restrictionbase="xs:string">
<xs:patternvalue="[A-Z][A-Z][A-Z]"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
下一个例子也定义了带有一个限定的名为 "initials" 的元素。可接受的值是大写或小写字母 a - z 其中的三个:
<xs:elementname="initials">
<xs:simpleType>
<xs:restrictionbase="xs:string">
<xs:patternvalue="[a-zA-Z][a-zA-Z][a-zA-Z]"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
下一个例子定义了带有一个限定的名为 "choice 的元素。可接受的值是字母 x, y 或 z 中的一个:
<xs:elementname="choice">
<xs:simpleType>
<xs:restrictionbase="xs:string">
<xs:pattern value="[xyz]"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
下一个例子定义了带有一个限定的名为 "prodid" 的元素。可接受的值是五个阿拉伯数字的一个序列,且每个数字的范围是 0-9:
<xs:elementname="prodid">
<xs:simpleType>
<xs:restrictionbase="xs:integer">
<xs:patternvalue="[0-9][0-9][0-9][0-9][0-9]"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
4) 对一系列值的其他限定
下面的例子定义了带有一个限定的名为 "letter" 的元素。可接受的值是 a - z 中零个或多个字母:
<xs:elementname="letter">
<xs:simpleType>
<xs:restrictionbase="xs:string">
<xs:patternvalue="([a-z])*"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
下面的例子定义了带有一个限定的名为 "letter" 的元素。可接受的值是一对或多对字母,每对字母由一个小写字母后跟一个大写字母组成。举个例子,"sToP"将会通过这种模式的验证,但是 "Stop"、"STOP" 或者 "stop" 无法通过验证:
<xs:elementname="letter">
<xs:simpleType>
<xs:restrictionbase="xs:string">
<xs:patternvalue="([a-z][A-Z])+"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
下面的例子定义了带有一个限定的名为 "gender" 的元素。可接受的值是 male 或者 female:
<xs:elementname="gender">
<xs:simpleType>
<xs:restrictionbase="xs:string">
<xs:patternvalue="male|female"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
下面的例子定义了带有一个限定的名为 "password" 的元素。可接受的值是由 8 个字符组成的一行字符,这些字符必须是大写或小写字母 a - z 亦或数字 0 - 9:
<xs:elementname="password">
<xs:simpleType>
<xs:restrictionbase="xs:string">
<xs:patternvalue="[a-zA-Z0-9]{8}"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
5) 对空白字符的限定
6) 对长度的限定
7) 数据类型的限定
五、复合类型
前面所讲到的都是简单类型,即元素里面只有内容,不包括属性或者其他元素。如果元素里面包含属性和其他元素,称之为复合类型
<?xml version="1.0" encoding="utf-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <!--元素note是一个复合元素,包含了一组序列--> <!--复合元素元素:包含其他子元素或属性--> <xs:element name="note"> <xs:complexType > <xs:sequence> <!--序列,子元素的顺序是固定--> <xs:element name="to" type="xs:string"></xs:element> <xs:element name="from" type="xs:string"></xs:element> <xs:element name="content" type="xs:string" minOccurs="1" maxOccurs="unbounded"></xs:element> </xs:sequence> <!--设置属性--> <xs:attribute name="sendtime" type="xs:string"></xs:attribute> </xs:complexType> </xs:element> </xs:schema> |
设置元素出现的次数使用minOccurs和maxOccurs表示最少出现多少次以及最多出多少次。
3. Schema 中的元素
六、综合示例:根元素school,包含很多个班级,班级包含很多个学生的xsd文件:
<?xml version="1.0" encoding="utf-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="school"> <xs:complexType> <xs:choice> <xs:element name="class" maxOccurs="unbounded"> <xs:complexType> <xs:choice> <xs:element name="student" maxOccurs="unbounded"> <xs:complexType> <xs:sequence> <xs:element name="stuname" type="xs:string"></xs:element> <xs:element name="stuage" type="xs:int"></xs:element> <xs:element name="stusex" type="xs:string"></xs:element> </xs:sequence> <xs:attribute name="stuid" type="xs:int"></xs:attribute> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> </xs:schema> |
<schema> 元素是每一个 XML Schema 的根元素:
七、示例:
示例1:
Xsd文件:
<?xmlversion="1.0"encoding="utf-8"?>
<xs:schemaxmlns:xs="http://www.w3.org/2001/XMLSchema" >
<xs:elementname="note">
<xs:complexType>
<xs:sequence>
<xs:elementname="to"type="xs:string"></xs:element>
<xs:elementname="from"type="xs:string"></xs:element>
<xs:elementname="heading"type="xs:string"></xs:element>
<xs:elementname="body"type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
XML文件:
<?xmlversion="1.0"encoding="utf-8"?>
<notexmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="t.xsd">
<to></to>
<from></from>
<heading></heading>
<body></body>
</note>
示例二:
XSD文件:
<?xmlversion="1.0"encoding="utf-8" ?> <xs:schemaxmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:elementname="school"> <xs:complexType> <xs:sequence> <xs:element name="student"minOccurs="1"maxOccurs="unbounded"> <xs:complexType> <xs:sequence> <xs:elementname="stuname" > <xs:complexType> <xs:simpleContent> <xs:extensionbase="xs:string"> <xs:attributename="stuid"type="xs:ID"></xs:attribute> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:elementname="stusex"type="xs:string"></xs:element> <xs:elementname="stuage"type="xs:int"></xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> |
XML文件
<?xmlversion="1.0"encoding="utf-8" ?> <schoolxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="XMLFile1.xsd"> <student> <stunamestuid="s1" >aa</stuname> <stusex >1</stusex> <stuage>3</stuage> </student> </school>
|