4.5 Schema内置类型

Schema提供了大量的内置类型,这些内置类型是派生其他简单类型的基础,因此读者需要熟记这些内置类型。Schema的内置类型继承关系如图4.2所示。

alt

图4.2 Schema的内置类型继承关系

备注:图4.2主要参考了XML Schema Part 2:Datatypes Second Edition的第3节:Built-in datatypes。读者可以通过http://www.w3.org/ TR/xmlschema-2/查看这份文档。

关于Schema内置数据类型的说明如表4.1所示。

表4.1 Schema的内置类型

alt

alt

备注:表4.1引自XML Schema Part 0: Primer Second Edition的2.3节:Simple Types。读者可以通过http://www.w3.org/TR/xmlschema-0/查看这份文档。

图4.2描绘了Schema内置数据类型的继承关系,表4.1则对这些内建类型进行了简单介绍。接下来我们将这些内建类型分成几大类逐一介绍。

4.5.1 字符串及相关类型

Schema里的字符串类型包括string和所有从string派生出来的类型,除此之外还包括QName。


alt注意

从Java继承逻辑来看,QName也应该由string派生而来——因为QName也是一种特殊的字符串,但由于Schema的派生机制与Java不同(只能通过限制、列表和联合的方式派生),因此Schema没有从string派生QName。


对字符串类型中的string、normalizedString和token而言,它们的作用基本相似,只是对待内容所包含空格的方式有所区别:

alt string:它会原封不动地保留字符串内容前面、后面及中间的所有空白。

alt normalizedString:它会将字符串内容中包含的换行、制表符和回车符都替换成空白。

alt token:它会将字符串内容中包含的换行、制表符和回车符都替换成空白,并自动删除字符串前后的空白,如果字符串中间包含多个连续的空白,多个连续的空白会被压缩成单个空白。

Name类型要求字符串内容是一个合法的XML标签名,即该类型的值可以由字母、数字、下画线(_)、中画线(-)、冒号(:)和点号(.)组成,且不能以数字、中画线(-)或点号(.)开头。

NCName类型要求字符串内容是一个不带命名空间前缀的XML标签名。因此它与Name类型的区别在于,它不能包含冒号(:)。

QName类型则要求字符串内容是一个带命名空间前缀的XML标签名,但它允许省略命名空间前缀——省略命名空间前缀后,QName类型的值不能以冒号开头。一旦在QName类型的值中使用了命名空间前缀,则该命名空间前缀必须有对应的命名空间。

下面的XML文档中包含了上面几种字符串类型的用法:

程序清单:codes\04\4.5\string.xml

alt

至于由string类型派生出来的ID、IDREF、IDREFS、ENTITY、ENTITIES、NMTOKEN和NMTOKENS等类型,与前面DTD中对应的类型完全相同,而且只能用来定义属性类型,故此处不再赘述。

4.5.2 数值类型

Schema的数值类型大致可分为如下3类:

alt 浮点数:主要有float和double。

alt 精确小数:decimal。

alt 整数:integer以及由该类型派生出来的各种数据类型。

float和double类型与Java里的float和double类型相似,float类型代表32位的单精度浮点数,double类型代表64位的双精度浮点数。

float和double类型的值既可以是普通小数值,如5.6,也可以是科学记数法表示的数值,如5.6e3(即5 600),其中的e既可以是大写字母(E),也可以是小写字母(e)。这与Java里的float和double类型完全一样。如果整数部分是0,则允许省略整数部分(但小数点不能省略)。


alt注意

XML Schema里的float类型的值无须添加f或F后缀。当我们在XML文档中输入5.6时,它既可以代表float类型的值,也可以代表double类型的值。


除此之外,float和double还可以接受如下几个特殊值:-INF(负无穷大)、INF(正无穷大)、NaN(非数)、+0(正零)和-0(负零)。其中,正零大于负零,NaN大于所有数值(包括INF),INF大于其他所有浮点数。

decimal类型有点类似于Java中的BigDecimal类,它表示精确小数。按照Schema的要求,decimal至少应该支持18位有效的小数。decimal与float和double有点相似,区别主要有如下3点:

alt decimal更精确,可保证18位有效的小数。

alt decimal不支持使用科学计数法。

alt decimal不支持-INF、INF和NaN等特殊值。

decimal派生了integer,integer代表一个任意大的整数。由integer间接或直接派生的所有类型都是整数类型。关于这些整数类型的说明如表4.2所示。

表4.2 内置整数类型

alt

alt


alt注意

MySQL中int和integer其实是同一个数据类型,Java中Integer是int的包装类,而Schema中integer代表任意大的整数,int代表32位的有符号整数,它们截然不同。读者千万不要搞混淆了。


下面的XML文档中包含了各种数据类型的示例:

程序清单:codes\04\4.5\number.xml

alt

4.5.3 日期、时间类型

XML Schema内置了大量日期、时间类型,这些日期、时间类型可用于表示各种类型的时间值。关于内置日期、时间类型的说明如表4.3所示。

表4.3 日期、时间类型

alt


alt注意

上述time、dateTime的格式字符串中都包含了指定毫秒的sss部分,指定毫秒的数字与指定秒的数字之间要用点号隔开。


下面的XML文档示范了上述各种日期、时间类型的值。

程序清单:codes\04\4.5\date.xml

alt

上述XML文档中<duration…/>元素的类型是duration,通过查看上面的XML文档,读者可以发现duration类型的值必须满足如下3个要求:

alt 前缀P是必需的。

alt nY、nM、nD、nH、nM和nS每个部分都可独立使用,分别表示一段时间。如果使用多个部分的组合,则表示多段时间累加。

alt 如果需要出现nH、nM和nS部分,必须使用T分隔符——即使没有nY、nM和nD部分。

4.5.4 boolean类型

boolean数据类型只能接受true、false(大小写不能改变)、0和1等4个值,如下有效的XML文档中<boolean…/>元素的类型是boolean:

程序清单:codes\04\4.5\boolean.xml

alt

4.5.5 anyURI类型

anyURI类型的值必须是一个合法URI(统一资源标识符),URI是一个比URL覆盖范围更广的概念,它完全包含URL。不仅如此,其他任何有效资源标识符都是有效的。如下有效的XML文档中<uri…/>元素的类型就是anyURI:

程序清单:codes\04\4.5\uri.xml

alt

4.5.6 二进制数据

XML Schema提供了2种二进制属性:hexBinary和base64Binary,关于这两种二进制类型的解释如下:

alt hexBinary:以十六进制数字保存的二进制数据,因此该类型的值只能由0~9、a~f和A~F(代表10~15)这几种字符组成。值得指出的是,hexBinary底层会映射成byte(8位)数组保存,而每个byte元素可保存2位的十六进制数字,因此这种数据类型的值的字符长度必须是偶数。

alt base64Binary:以Base64编码保存的任意二进制数据。读者可能会被所谓的Base64编码“吓到”,不过可以不去管这些细节,而只要记住这种类型的值能由a~z、A~Z、0~9和加号(+)等字符组成,而且base64Binary的二进制码的长度必须是64的倍数。前面提到的a~z、A~Z、0~9和加号(+)等每个字符只需2个字节(16位),因此这种数据类型的值的字符长度必须是4的倍数。

如下有效的XML文档中包含了一个hexBinary类型的<wawa…/>元素,还包含了一个base64Binary类型的<haha…/>元素:

程序清单:codes\04\4.5\binary.xml

alt

熟练掌握上面的Schema类型之后,就可以利用这些类型来定义元素和属性。如果希望为元素、属性定义更细致的语义约束,则需要派生新的数据类型。