XML Schema
0 概述
XML Schema 的作用是定义 XML 文档的合法构建模块,类似 DTD。它的作用如下:
- 定义可出现在文档中的元素
- 定义可出现在文档中的属性
- 定义哪个元素是子元素
- 定义子元素的次序
- 定义子元素的数目
- 定义元素是否为空,或者是否可包含文本
- 定义元素和属性的数据类型
- 定义元素和属性的默认值以及固定值
XML Schema是DTD的替代方案,对比难以理解且又不灵活的DTD,XML Schema有一下优点:
- XML Schema 可针对未来的需求进行扩展
- XML Schema 更完善,功能更强大
- XML Schema 基于 XML 编写
- XML Schema 支持数据类型
- XML Schema 支持命名空间
1 XML和XML Schema申明
在一般xml文档的根元素中经常会有一堆URI,那么他们有什么作用呢?例如下面的xml文档:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3school.com.cn note.xsd">
George
John
Reminder
Don't forget the meeting!
其根元素每一部分的作用如下:
xmlns="http://www.w3school.com.cn"
这一段规定了默认命名空间的声明。此声明会告知 schema 验证器,在此 XML 文档中使用的所有元素都被声明于 "http://www.w3school.com.cn" 这个命名空间;
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
这一段告知XML解析器根据某个 schema 来验证此文档;
xsi:schemaLocation="http://www.w3school.com.cn note.xsd"
这一段则进一步标识了要使用的 XML schema 的位置。
同样,因为schema也是用xml编写的,因此schema的根元素中也会有一堆类似的申明,例如对于如下schema
targetNamespace="http://www.w3school.com.cn"
xmlns="http://www.w3school.com.cn"
elementFormDefault="qualified">
...
下面的片断:
xmlns:xs="http://www.w3.org/2001/XMLSchema"
显示 schema 中用到的元素和数据类型来自命名空间 "http://www.w3.org/2001/XMLSchema"。同时它还规定了来自命名空间 "http://www.w3.org/2001/XMLSchema" 的元素和数据类型应该使用前缀 xs:
这个片断:
targetNamespace="http://www.w3school.com.cn"
显示被此 schema 定义的元素 (note, to, from, heading, body) 的命名空间为: "http://www.w3school.com.cn"。
这个片断:
xmlns="http://www.w3school.com.cn"
指出默认的命名空间是 "http://www.w3school.com.cn"。(在指定了xmlns:xs属性后,默认命名空间是不是就没什么意义了呢?)
elementFormDefault="qualified"
指出任何 XML 实例文档所使用的且在此 schema 中声明过的元素必须被命名空间限定。
2 XSD(XML Schema Definition)数据类型
Schema中第一的元素或者属性,其值都是有类型的。这个类型可以是Schema的内置类型,也可以是自定义的复杂类型。本节介绍Schema的内置类型。
2.1 字符串数据类型
2.1.1 字符串数据类型
字符串数据类型用于可包含字符串的值,包括:字符、换行、回车以及制表符。
下面是一个关于某个 scheme 中字符串声明的例子:
文档中的元素看上去应该类似这样:
John Smith
或者类似这样:
John Smith
注释:如果您使用字符串数据类型,XML 处理器就不会更改其中的值。
2.1.2 规格化字符串类型
规格化字符串数据类型源自于字符串数据类型。同样可包含字符,但是 XML 处理器会移除换行,回车以及制表符。
下面是一个关于在某个 schema 中规格化字符串数据类型的例子:
文档中的元素看上去应该类似这样:
John Smith
或者类似这样:
John Smith
注释:在上面的例子中,XML 处理器会使用空格替换所有的制表符。
2.1.3 Token数据类型
Token 数据类型同样源自于字符串数据类型,同样可包含字符,但是 XML 处理器会移除换行符、回车、制表符、开头和结尾的空格以及(连续的)空格。
下面是在 schema 中一个有关 token 声明的例子:
文档中的元素看上去应该类似这样:
John Smith
或者类似这样:
John Smith
注释:在上面这个例子中,XML 解析器会移除制表符。
2.1.4 字符串数据类型汇总
除了上述提及的3种字符串类型,还有其他的继生于字符串数字类型的类型,如下:
名称 |
描述 |
ENTITIES |
|
ENTITY |
|
ID |
在 XML 中提交 ID 属性的字符串 (仅与 schema 属性一同使用) |
IDREF |
在 XML 中提交 IDREF 属性的字符串(仅与 schema 属性一同使用) |
IDREFS language |
包含合法的语言 id 的字符串 |
Name |
包含合法 XML 名称的字符串 |
NCName |
|
NMTOKEN |
在 XML 中提交 NMTOKEN 属性的字符串 (仅与 schema 属性一同使用) |
NMTOKENS |
|
而可与字符串数据类型一同使用的限定有(关于限定的内容后面再详细说明):
- enumeration
- length
- maxLength
- minLength
- pattern (NMTOKENS、IDREFS 以及 ENTITIES 无法使用此约束)
- whiteSpace
2.2 日期和实践数据类型
2.2.1 日期数据类型
日期数据类型用于定义日期,日期使用此格式进行定义:"YYYY-MM-DD",其中:YYYY 表示年份;MM 表示月份;
DD 表示天数。所有的成分都是必需的!
下面是一个有关 schema 中日期声明的例子:
文档中的元素看上去应该类似这样:
2002-09-24
如需对日期规定一个时区,您也可以通过在日期后加一个 "Z" 的方式,使用世界调整时间(UTC time)来输入一个日期 - 比如这样:
2002-09-24Z
或者也可以通过在日期后添加一个正的或负时间的方法,来规定以世界调整时间为准的偏移量 - 比如这样:
2002-09-24-06:00
或者:
2002-09-24+06:00
2.2.2 时间数据类型
时间数据类型用于定义时间,时间使用下面的格式来定义:"hh:mm:ss",其中hh 表示小时;mm 表示分钟;
ss 表示秒。所有的成分都是必需的!
下面是一个有关 schema 中时间声明的例子:
文档中的元素看上去应该类似这样:
09:00:00
或者类似这样:
09:30:10.5
如需规定一个时区,您也可以通过在时间后加一个 "Z" 的方式,使用世界调整时间(UTC time)来输入一个时间 - 比如这样:
09:30:10Z
或者也可以通过在时间后添加一个正的或负时间的方法,来规定以世界调整时间为准的偏移量 - 比如这样:
09:30:10-06:00
或者:
09:30:10+06:00
2.2.3 日期时间数据类型
日期时间数据类型用于定义日期和时间,日期时间使用下面的格式进行定义:"YYYY-MM-DDThh:mm:ss",每一部分的含义同日期数据类型和时间数据类型(而T 表示时间部分的开始)。同样,所有的成分都是必需的!
下面是一个有关 schema 中日期时间声明的例子:
文档中的元素看上去应该类似这样:
2002-05-30T09:00:00
或者类似这样:
2002-05-30T09:30:10.5
如需规定一个时区,您也可以通过在日期时间后加一个 "Z" 的方式,使用世界调整时间(UTC time)来输入一个日期时间 - 比如这样:
2002-05-30T09:30:10Z
或者也可以通过在时间后添加一个正的或负时间的方法,来规定以世界调整时间为准的偏移量 - 比如这样:
2002-05-30T09:30:10-06:00
或者:
2002-05-30T09:30:10+06:00
2.2.4 持续时间数据类型
持续时间数据类型用于规定时间间隔,时间间隔使用下面的格式来规定:"PnYnMnDTnHnMnS",其中:
- P 表示周期(必需)
- nY 表示年数
- nM 表示月数
- nD 表示天数
- T 表示时间部分的起始 (如果您打算规定小时、分钟和秒,则此选项为必需)
- nH 表示小时数
- nM 表示分钟数
- nS 表示秒数
下面是一个有关 schema 中持续时间声明的例子:
文档中的元素看上去应该类似这样:
P5Y
上面的例子表示一个 5 年的周期。
或者类似这样:
P5Y2M10D
上面的例子表示一个 5 年、2 个月及 10 天的周期。
或者类似这样:
P5Y2M10DT15H
上面的例子表示一个 5 年、2 个月、10 天及 15 小时的周期。
或者类似这样:
PT15H
上面的例子表示一个 15 小时的周期。
如需规定一个负的持续时间,请在 P 之前输入减号:
-P10D
上面的例子表示一个负 10 天的周期???
2.2.5 日期时间数据类型综合
除上述的日期和时间数据类型之外,还有其他形式的日期和时间数据类型,如下:
名称 |
描述 |
gDay |
定义日期的一个部分 - 天 (DD) |
gMonth |
定义日期的一个部分 - 月 (MM) |
gMonthDay |
定义日期的一个部分 - 月和天 (MM-DD) |
gYear |
定义日期的一个部分 - 年 (YYYY) |
gYearMonth |
定义日期的一个部分 - 年和月 (YYYY-MM) |
time |
定义一个时间值 |
可与日期数据类型一同使用的限定则有:
- enumeration
- maxExclusive
- maxInclusive
- minExclusive
- minInclusive
- pattern
- whitespace
2.3 数值数据类型
2.3.1 十进制数据类型
十进制数据类型用于规定一个数值,可规定的十进制数字的最大位数是 18 位(其实就是浮点数)。下面是一个关于某个 scheme 中十进制数声明的例子。
文档中的元素看上去应该类似以下情况:
999.50
+999.5450
-999.5230
0
14
2.3.2 数字数据类型综合
可用的数字数据类型共有:
名字 |
秒数 |
byte |
有正负的 8 位整数 |
decimal |
十进制数 |
int |
有正负的 32 位整数 |
integer |
整数值 |
long |
有正负的 64 位整数 |
negativeInteger |
仅包含负值的整数 ( .., -2, -1.) |
nonNegativeInteger |
仅包含非负值的整数 (0, 1, 2, ..) |
nonPositiveInteger |
仅包含非正值的整数 (.., -2, -1, 0) |
positiveInteger |
仅包含正值的整数 (1, 2, ..) |
short |
有正负的 16 位整数 |
unsignedLong |
无正负的 64 位整数 |
unsignedInt |
无正负的 32 位整数 |
unsignedShort |
无正负的 16 位整数 |
unsignedByte |
无正负的 8 位整数 |
而可与数值数据类型一同使用的限定有:
Enumeration、fractionDigits、maxExclusive、maxInclusive、minExclusive、minInclusive、pattern、totalDigits、whiteSpace