知优码

您现在的位置是:首页 > WEB相关 > XML文档

XML文档

XML-XSD简单数据类型

知优码 2019-11-17XML文档
XSD提供了数据类型,并且支持自定义数据类型,但这一切都是建立在XSD内置数据类型和一套扩展内置数据类型的规则基础之上的,在这一篇笔记中,就来看看XSD中的数据类型。1、XSD数据类型图先看一下数据类

  XSD提供了数据类型,并且支持自定义数据类型,但这一切都是建立在XSD内置数据类型和一套扩展内置数据类型的规则基础之上的,在这一篇笔记中,就来看看XSD中的数据类型。

1、XSD数据类型图

先看一下数据类型图,有个大概的轮廓,后面再进一步细化:

从上面的XSD数据类型图可以看出,主要分成两个大类:

(1)简单类型:可以给属性使用,也可以给元素使用,除了内建类型,也可以使用<simpleType>自定义简单类型,而自定义的方式有三种:限制<restriction>、列表<list>、联合<union>。

(2)复杂类型:只能给元素使用,并且全部需要使用<complexType>来自定义,根据内容又可进一步区分为含简单内容的复杂类型和含复杂内容的复杂类型,分别使用<simpleContent>和<complexContent>定义其内容。另外,复杂类型还可以使用限制<restriction>和扩展<extension>来派生新的类型。

复杂类型只能给元素使用,这大概也是为什么要区分简单类型和复杂类型的原因。

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>元素自定义简单数据类型的语法如下:

<simpleType id=ID name=NCName final=... any-attributes>
    (annotation?,(restriction|list|union))
    <!--
     1.id属性是可选的,用于唯一标识<simpleType>元素本身
     2.name属性表示自定义数据类型的名称,值是NCName类型,并且必须在所有<simpleType>和<complexType>之间唯一,<simpleType>是<schema>的子元素时必须指定,这个时候新定义的数据类型为全局的数据类型
    -->
</simpleType>

(2)可以在schema元素下定义全局数据类型,也可以在其它元素下定义局部数据类型。

(3)属性final用来限制派生新的类型,默认值为根元素<schema>的finalDefault属性的值,可以取的值有:

A、#all:限制该类型以任何形式派生新的类型

B、restriction、list、union的自由组合:限制使用指定的方式派生新的类型

C、"":不做任何限制

4、通过限制派生自定义数据类型

  从语法上看,使用<simpleType>元素自定义简单类型,具体有三种方式:限制<restriction>、列表<list>、联合<union>。这一小节先看第一种:限制<restriction>。

(1)语法格式如下:

<simpleType ...>
    <restriction id=ID base=QNAME any-attributes>
    <!--1.处于<simpleType>元素下的语法-->
        (annotation?,(simpleType?,(12种数据类型约束)*))
    </restriction>
</simpleType>

<simpleContent ...>
    <restriction id=ID base=QNAME any-attributes>
    <!--2.处于<simpleContent>元素下的语法-->
        (annotation?,(simpleType?,(12种数据类型约束)*)?,((attribute|attributeGroup)*,anyAttribute?))
    </restriction>
</simpleContent>

<complextContent ...>
    <restriction id=ID base=QNAME any-attributes>
    <!--3.处于<complextContent>元素下的语法-->
         (annotation?,(group|all|choice|sequence)?,((attribute|attributeGroup)*,anyAttribute?))
    </restriction>
</complextContent>

其中id属性唯一标识<restriction>元素本身,可选的;base属性表示在该schema(或由指定命名空间指示的其它schema)中定义的内建数据类型、simpleType或complexType元素的名称,也可以不指定base属性,而直接使用<simpleType>子元素来定义被限制的基类型。

(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)。

5、通过列表派生自定义数据类型
(1)列表<list>元素的语法:
<list id=ID itemType=QName any-attributes>
   (annotatin?,(simpleType?))
</list>

(2)指定列表成员类型的方法
A、使用itemType属性

B、使用子元素<simpleType>,这个时候不能指定itemType属性

(3)实际上,内置的IDREFS、ENTITIES、NMTOKENS分别是IDREF、ENTITY、NMTOKEN类型的列表类型。

(4)使用空格作为列表类型值的分隔符。

(5)可以对列表类型使用长度约束(约束列表项的个数)、枚举约束、正则表达式约束和空白处理约束(但值只能是collapse),需要注意的是,枚举约束和正则表达式约束的是整个列表类型的值,而不仅仅只是其中一个列表项值。

6、通过联合派生自定义数据类型

(1)联合<union>元素的语法:

<union id=ID memberTypes="QName列表" any-attributes>
   (annotatin?,(simpleType*))
</union>

(2)指定联合成员类型的方法

A、使用属性memberTypes,多个类型使用空格分隔

B、使用一个或多个子元素<simpleType>

(3)可以对联合类型使用枚举约束和正则表达式约束,同样,约束的也是整个联合类型的值。

(4)列表类型和联合类型都是在现有类型的基础上派生新类型,在XSD中还可以使用<list>元素由联合类型派生出相应的列表类型,也可以使用<union>元素将一个或多个已有的列表类型派生出新的联合类型,不过需要注意的是,不能使用列表类型派生新的列表类型,也不能使用含有列表类型的联合类型派生新的列表类型。

7、最后看一个使用三种方式自定义简单类型的实例:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
  <!--从int派生的ageType-->
  <xs:simpleType name="ageType">
     <xs:restriction base="xs:int">
         <xs:maxInclusive value="100"/>
         <xs:minInclusive value="0"/>
     </xs:restriction>
  </xs:simpleType>
  <!--由ageType派生出对应的列表类型-->
  <xs:simpleType name="ageListType">
      <xs:list itemType="ageType"/>
  </xs:simpleType>

  <!--从string派生的nameType-->
  <xs:simpleType name="nameType">
     <xs:restriction base="xs:string">
         <xs:maxLength value="20"/>
         <xs:minLength value="4"/>
     </xs:restriction>
  </xs:simpleType>
  <!--由nameType派生出对应的列表类型-->
  <xs:simpleType name="nameListType">
      <xs:list itemType="nameType"/>
  </xs:simpleType>
  
  <!--由ageType和nameType派生出联合类型-->
  <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>