XSD提供了数据类型,并且支持自定义数据类型,但这一切都是建立在XSD内置数据类型和一套扩展内置数据类型的规则基础之上的,在这一篇笔记中,就来看看XSD中的数据类型。
1、XSD数据类型图
先看一下数据类型图,有个大概的轮廓,后面再进一步细化:
从上面的XSD数据类型图可以看出,主要分成两个大类:
(1)简单类型:可以给属性使用,也可以给元素使用,除了内建类型,也可以使用、联合
(2)复杂类型:只能给元素使用,并且全部需要使用
复杂类型只能给元素使用,这大概也是为什么要区分简单类型和复杂类型的原因。
2、内建类型
内建类型具有基本的重要地位,是派生其它类型的基础,首先还是从官方文档中截一副内建类型的继承关系图下来:
图例中的几个说明:built-in primitive types(内建基本类型)、built-in derived types(内建派生类型)、complex types(复杂类型)、derived by restriction(通过限制派生)、derived by list(通过列表派生)、derived by extension or restriction(通过限制或扩展派生)。
第一印象看这幅图,似乎是两根柱子(string及其派生、decimal及其派生)上面架设了两层商铺,柱子是脊梁,商铺是装饰——扯远了点,还是具体的看看这些内建类型吧!
(1)字符串类型
注意QNAME虽然是字符串类型数据,但因为派生机制的问题,并不是派生自string。
类型 | 说明 | ||||||
QNAME | 带命名空间前缀的XML标签名,允许省略命名空间,但省略时不能以冒号开头,并且使用命名空间时不能以冒号结尾 | ||||||
string | 字符串,可包括字符、换行、回车以及制表符等,会原封不动保留所有字符 | ||||||
normalizedString | 会将字符串中的换行、回车以及制表符都替换成空格 | ||||||
token | 将换行、回车及制表符替换成空格,并自动删除前后空格,将中间的多个连续空格压缩成一个空格 | ||||||
language | 合法的语言代码,如en-GB、en-US、fr、zh-CN等 | ||||||
Name | 合法的XML标签名,即由字母、数字、下划线、中划线、冒号、点号组成,且不能以数字、中划线、点号开头 | ||||||
NCName | 不带命名空间的合法的XML标签名,即不能含冒号 | ||||||
ID | 同DTD,在XML文档中必须唯一,只能用于属性,不能用于元素。 | ||||||
IDREF | 同DTD,必须是引用已有的ID属性值,只能用于属性,不能用于元素 | ||||||
IDREFS | 同DTD,必须是引用已有的一个或多个ID属性值,多个使用空格分隔,只能用于属性,不能用于元素 | ||||||
ENTITY | 同DTD,外部实体,只能用于属性,不能用于元素 | ||||||
ENTITIES | 同DTD,一个或多个外部实体,多个使用空格分隔,只能用于属性,不能用于元素 | ||||||
NMTOKEN | 同DTD,合法的XML标签名,且只能由字母、数字、下划线、中划线、点号、冒号组成 | ||||||
NMTOKENS | 同DTD,一个或多个NMTOKEN,多个使用空格分隔,只能用于属性,不能用于元素 |
(2)数值类型
float和double类型还可以接受的特殊值:-INF(负无穷大)、INF(正无穷大),NaN(非数)、+0(正零)和-0(负零)。其中正零大于负零,NaN大于所有数值(包括INF),INF大于所有浮点数。
类型 | 说明 | ||||||
float | 32位的单精度浮点数,可使用科学计数法,整数部分为0时可省略,但不能省略小数点,不能用f/F后缀 | ||||||
double | 64位的双精度浮点数,可使用科学计数法,整数部分为0时可省略,但不能省略小数点 | ||||||
decimal | 精确小数,不能使用科学计数法,不能接受-INF、INF、NaN等特殊值 | ||||||
integer | 代表任意大的整数 | ||||||
nonPositiveInteger | 非正整数 | ||||||
negativeInteger | 负整数 | ||||||
long | 64位的有符号整数 | ||||||
int | 32位的有符号整数 | ||||||
short | 16位的有符号整数 | ||||||
byte | 8位的有符号整数 | ||||||
nonNegativeInteger | 非负整数 | ||||||
positvieInteger | 正整数 | ||||||
unsignedLong | 64位的无符号整数 | ||||||
unsignedInt | 32位的无符号整数 | ||||||
unsignedShort | 16位的无符号整数 | ||||||
unsignedByte | 8位的无符号整数 |
(3)布尔类型
布尔类型可以接受true、false、1(表示true)、0(表示false)四个值。
(4)日期和时间类型
类型 | 格式 | 说明 |
date | YYYY-MM-DD | 日期 |
time | hh:mm:ss.sss | 时间,sss表示毫秒数 |
dateTime | YYYY-MM-DDThh:mm:ss.sss | 日期时间,中间的T是必须的,是日期和时间的分隔符 |
gYear | YYYY | 年 |
gYearMonth | YYYY-MM | 年月 |
gMonth | --MM | 月,前面的两个中划线是必须的 |
gMonthDay | --MM-DD | 月日,前面的两个中划线是必须的 |
gDay | ---DDD | 日,前面的三个中划线是必须的 |
duration | PnYnMnDTnHnMnS | 定义时间间隔,P是固定的,表示周期,S前的n可以有小数部分,其它必须是整数 |
说明:上面列出的前8个类型后面可以添加Z表示UTC时间;Y、M、D、h、m、s分别表示年月日时分秒,都可替换为一个有效的整数,其中,年份不够4位左边补0,前面加负号表示公元前,月日时分秒不够2位左边补0,毫秒sss可以是1-3位的整数。
(5)二进制数据类型
XSD中有下面两种二进制数据类型:
A:hexBinary,以十六进制保存的二进制数据,因此只能由0~9、a~f、A~F等字符组成,字符长度必须是偶数。
B:base64Binary,以Base64编码保存的任意二进制数据,因此只能由0~9、a~f、A~F和加号+等字符组成,字符长度必须是4的倍数。
(6)anyURI类型:合法的URI。
(7)NOTATION类型:同DTD,表示合法的符号。
3、自定义简单数据类型
(1)使用
<simpleType id=ID name=NCName final=... any-attributes> (annotation?,(restriction|list|union)) simpleType>
(2)可以在schema元素下定义全局数据类型,也可以在其它元素下定义局部数据类型。
(3)属性final用来限制派生新的类型,默认值为根元素
A、#all:限制该类型以任何形式派生新的类型
B、restriction、list、union的自由组合:限制使用指定的方式派生新的类型
C、"":不做任何限制
4、通过限制派生自定义数据类型
从语法上看,使用、联合
(1)语法格式如下:
<simpleType ...> <restriction id=ID base=QNAME any-attributes> (annotation?,(simpleType?,(12种数据类型约束)*)) restriction> simpleType> <simpleContent ...> <restriction id=ID base=QNAME any-attributes> (annotation?,(simpleType?,(12种数据类型约束)*)?,((attribute|attributeGroup)*,anyAttribute?)) restriction> simpleContent> <complextContent ...> <restriction id=ID base=QNAME any-attributes> (annotation?,(group|all|choice|sequence)?,((attribute|attributeGroup)*,anyAttribute?)) restriction> complextContent>
其中id属性唯一标识
(2)约束:在XSD中,限制是通过在基类型上添加约束来实现的,那么,又有哪些约束呢?这些约束又可以应用到哪些基类型呢?
分类 | 可作用的数据类型 | 约束 | 描述 |
枚举约束 | enumeration | 可接受值的列表 | |
精度约束 | decimal | fractionDigits | 允许的最多的小数位数 |
totalDigits | 允许的数字的最多位数(不包括小数点) | ||
长度约束 | string、QName、anyURI、二进制数据 还可用于约束列表类型列表项的数目 |
length | 字符长度或者列表项目的数目 |
maxLength | 字符长度或者列表项目的数目的最大值 | ||
minLength | 字符长度或者列表项目的数目的最小值 | ||
范围约束 | 可以比较大小的类型,如数值、日期等 | maxExclusive | 允许数值的上限,不能等于上限值 |
minExclusive | 允许数值的下限,不能等于下限值 | ||
maxInclusive | 允许数值的上限,可等于上限值 | ||
minInclusive | 允许数值的下限,可等于下限值 | ||
正则表达式约束 | 各种数据类型 | pattern | 使用正则表达式约束可以出现的字符 |
空白处理约束 | whiteSpace | 定义空白字符(换行、回车、空格、制表等)的处理方式 preserve:原样保留所有空白 replace:替换所有空白字符为空格 collapse:先replace,再去掉首尾空格,并将中间连续空格压缩为一个 |
在派生新的类型时,如果原来类型有一个约束,新派生类型使用相同的约束,且新约束范围在原约束范围之内,则新类型的约束将会覆盖原类型的约束。但有时候,想阻止派生类型覆盖已有的约束,这个时候可以在原类型的约束上添加fixed属性(true|false)。
- 元素的语法:
<list id=ID itemType=QName any-attributes> (annotatin?,(simpleType?)) list>
(2)指定列表成员类型的方法
A、使用itemType属性
B、使用子元素
(3)实际上,内置的IDREFS、ENTITIES、NMTOKENS分别是IDREF、ENTITY、NMTOKEN类型的列表类型。
(4)使用空格作为列表类型值的分隔符。
(5)可以对列表类型使用长度约束(约束列表项的个数)、枚举约束、正则表达式约束和空白处理约束(但值只能是collapse),需要注意的是,枚举约束和正则表达式约束的是整个列表类型的值,而不仅仅只是其中一个列表项值。
6、通过联合派生自定义数据类型
(1)联合
<union id=ID memberTypes="QName列表" any-attributes> (annotatin?,(simpleType*)) union>
(2)指定联合成员类型的方法
A、使用属性memberTypes,多个类型使用空格分隔
B、使用一个或多个子元素
(3)可以对联合类型使用枚举约束和正则表达式约束,同样,约束的也是整个联合类型的值。
(4)列表类型和联合类型都是在现有类型的基础上派生新类型,在XSD中还可以使用元素由联合类型派生出相应的列表类型,也可以使用
7、最后看一个使用三种方式自定义简单类型的实例:
xml version="1.0" encoding="UTF-8" standalone="yes"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:simpleType name="ageType"> <xs:restriction base="xs:int"> <xs:maxInclusive value="100"/> <xs:minInclusive value="0"/> xs:restriction> xs:simpleType> <xs:simpleType name="ageListType"> <xs:list itemType="ageType"/> xs:simpleType> <xs:simpleType name="nameType"> <xs:restriction base="xs:string"> <xs:maxLength value="20"/> <xs:minLength value="4"/> xs:restriction> xs:simpleType> <xs:simpleType name="nameListType"> <xs:list itemType="nameType"/> xs:simpleType> <xs:simpleType name="ageType_nameType"> <xs:union memberTypes="ageType nameType"/> xs:simpleType> <xs:simpleType name="ageListType_nameListType"> <xs:union memberTypes="ageListType nameListType"/> xs:simpleType> <xs:simpleType name="furtherType"> <xs:union memberTypes="ageType_nameType ageListType_nameListType"/> xs:simpleType> <xs:simpleType name="furtherMixType"> <xs:union memberTypes="nameListType ageListType_nameListType"/> xs:simpleType> <xs:simpleType name="ageType_nameType_ListType"> <xs:list itemType="ageType_nameType"/> xs:simpleType> xs:schema>