XML Schema(W3C)数据类型
XML Schema数据类型总体上分为简单类型和复杂类型。掌握了这部分的知识就掌握了它70%的内容。
简单类型
简单类型细分之后大概的结构如下:
内置基本类型:该类型与其它计算机语言中所提供的数据类型相似,有以下类型:string,boolean,float,double,decimal,time,datatime。比较特殊的是:duration(持续的日期/时间数据,格式为:PYYMMDDTHHMMSS),hexBinary(十六进制表示的二进制数据),anyURI(URL网址)等,W3C标准的内置数据类型多达44种。为保持与DTD的兼容性,其中ID、ENTITY、NOTATION等仅用于属性。
内置派生类型:从内置基本类型中派生出的类型,有多达25种。如:normalizedString,language,integer,int,ENTITY,IDREFS,byte等。派生方式有三种:一是限制,使用
<restriction…/>
;二是列表,使用<list…/>
;三是联合,使用<union…/>
。Schema的内置类型有复杂的层次关系,但没有对象概念。结构如下图所示:
内置数据类型:在Schema中可使用simpleType元素自定义符合用户要求的数据类型,所定义的简单类型元素语法格式如下:
<xsd:element name="简单元素名" type="元素类型名"/> <xsd:simpleType name="元素类型名" /> 元素类型定义内容 </xsd:simpleType> <xsd: restriction base=Qname > restriction约束内容</xsd:restriction> <xsd:list itemType=Qname> list约束内容</xsd:list> <xsd:union memberTypes=List of Qname>union约束内容</xsd:union> </xsd:simpleType>
w3c简单类型元素格式中的restriction、list和union是可选项。
注意:满足以下两个条件的元素才适合定义为简单类型元素 :第一,元素内容是内置数据类型值,如字符串、日期等;第二,元素中不包含属性。
实例
示例2:设计一个**简单类型元素**UniqueID(存放身份证号码)
<xsd:element name="UniqueID" type="IDType"/>
<xsd:simpleType name="IDType">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="18"/>
<xsd:pattern value="[0-9]*"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
示例3:设计一个描述工作日的**简单元素类型**WorkDay
<xs:simpleType name="workDay">
<xs:restriction base="xs:string">
<xs:enumeration value="Mon"/>
<xs:enumeration value="Tue"/>
<xs:enumeration value="Wed"/>
<xs:enumeration value="Thu"/>
<xs:enumeration value="Fri"/>
</xs:restriction>
</xs:simpleType>
复杂类型
用complexType定义。
该元素的模式有:简单内容、复杂内容、约束和扩展等。
如果元素的内容是简单数据类型,包含属性,且只有一个约束<restriction…/>
或扩展<extension…/>
的子元素,则可采用简单内容模式<simpleContent…/>
方式定义。约束或扩展都是在已有类型基础上派生出新的复杂类型。假如元素包括除了约束或扩展之外的其它子元素,则不能用简单内容方式。
简单内容模式
示例:为 book_Type 的复杂类型元素设计一个新属性isbn用复杂内容方式定义。
<xsd:complexType name="book_Type">
<xsd:simpleContent>
<!-- 以decimal类型为基础扩展出新类型isbn-->
<xsd:extension base="xsd:decimal">
<xsd:attribute name="isbn" type="xsd:token"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
复杂内容模式
定义格式:
<element name="元素名" type="数据类型"/>
<complexType name="数据类型">
<complexContent>
<sequence>
<element name="子元素1">
<element name="子元素2">
…
</sequence>
</complexContent>
</complexTyep>
其中,sequence是顺序限制,还可以有约束(restriction)、扩展(extention)等其它几种限制。complexContent有时可省略。
另外一种参照定义方式的格式如下:
<element 简单元素名1>
<element 简单元素名2>
<element name="元素名" type="dataType"/>
<complexType name="dataType">
<sequence>
<element ref="简单元素名1">
<element ref="简单元素名2">
</sequence>
</complexTyep>
实例:
<?xml version="1.0" encoding="GB2312"?>
<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema">
<xsd:element name="title" type="xsd:string"/>
<xsd:element name="author" type="xsd:string"/>
<xsd:element name="book" type="dataType"/>
<xsd:complexType name="dataType">
<xsd:sequence>
<xsd:element name="ISBN" type="xsd:string"/>
<xsd:element ref="title"/>
<xsd:element ref="author"/>
</xsd:sequence>
</xsd:complexTyep>
</xsd:schema>
由于使用参照定义方式,可以让多个元素同时共享ISBN、title、author元素的设置,提高元素的复用性,例如book与magzine都有title与author。
W3C在complexType元素中对子元素的约束如下表:
All | 所有子元素都应出现,且只能出现一次,各个子元素可以任何顺序排列。 |
---|---|
sequence | 子元素只能依规定顺序排列 |
Choice | 子元素选择其中之一 |
Group | 将基本XML元素建立为一个组 |
simpleContent | 没有子元素只有数据内容、属性 |
complexContent | 只有XML子元素或空元素 |
Schema属性的声明
基本格式:
<element name="元素名" type="数据类型"/>
<complexType name="数据类型">
<attribute name="属性名" type="属性的数据类型" use="use值" default="值" fixed="值"/>
</complexType>
注意:
属性只能是简单数据类型,可以是内置数据类型或由simpleType元素所定义的自定义类型。
Use值共有三种选择:optional-表示该属性可有可无;required-表示该属性可为任何值,但必须出现一次;prohibited-表示该属性要与restriction元素一起使用进行约束。
XML Schema中的标记与实体
Schema中标记的使用
DTD一样,Schema中同样支持标记,也用notation元素。该元素中可以设定的属性有id、name、public、system。下面是一个案例:
?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<!-- 定义2个标记 -->
<xs:notation name="pdf" public="application/pdf" system="e:/tools/Foxit Reader.exe"/>
<xs:notation name="wmv" public="video/x-ms-wmv" system="wmplayer.exe"/>
<xs:element name="book">
<xs:complexType>
<!-- 定义一个NOTATION类型的type属性 -->
<xs:attribute name="type">
<xs:simpleType>
<xs:restriction base="xs:NOTATION">
<xs:enumeration value="pdf"/>
<xs:enumeration value="wmv"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
其中:
- id属性指定该标记的唯一标识,通常无须指定;
- name属性指定该标记的名称,该名称在整个Schema内部必须是唯一的,且该属性不能空缺;
- public属性指定该标记所标识的数据是什么格式(文件后缀)。该属性也不能空缺;
system属性指定该标记所标识的数据应当交给哪个应用程序去处理。该属性可空缺。
一个符合上述Schema约束的XML文档如下:
<?xml version="1.0" encoding="UTF-8"?>
<book xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="notation.xsd"
type="pdf"/>
W3C的Schema实体
先看一个实例:city 元素用一个实体来替换并实现 Montréal中的 é。
DTD中的实现方案:
<?xml version="1.0" ?>
<!DOCTYPE purchaseOrder [ <!ENTITY eacute "é"> ]>
<purchaseOrder xmlns="http://www.example.com/PO1" orderDate="1999-10-20">
<!-- etc. -->
<city>Montréal</city>
<!-- etc. -->
</purchaseOrder>
Schema中的实现方案:
<xsd:element name="eacute" type="xsd:token" fixed="é"/>
<?xml version="1.0" ?>
<purchaseOrder xmlns="http://www.example.com/PO1" xmlns:c="http://www.example.com/characterElements" orderDate="1999-10-20">
<!-- etc. -->
<city>Montr<c:eacute/>al</city>
<!-- etc. -->
</purchaseOrder>
W3C的Schema没有另外设置专用的实体,一般通过组元素来实现实体的定义和引用。
anyType类型
与DTD中的ANY类型相似,实际上就是对元素没限制。如:
<xsd:element name="book_list" type="xsd:anyType"/>
<!--设定书目的一个desc属性-->
<xsd:attribute name="desc" type="xsd:string"/>
<!--设定一个book元素-->
<xsd:element name="book">
<xsd:simpleType>
…..
</xsd:simpleTyep>
</xsd:element>
Schema设计案例
示例一:限制数值位数
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<!-- 新定义了一种数据类型:price_Type -->
<xs:simpleType name="price_Type">
<!-- 没有指定base属性,将以其simpleType子元素定义的类型作为基类型 -->
<xs:restriction>
<xs:simpleType>
<!-- 以decimal为基类型 -->
<xs:restriction base="xs:decimal">
<!-- 最多5位数,小数点后最多2位数 -->
<xs:fractionDigits value="2"/>
<xs:totalDigits value="5"/>
</xs:restriction>
</xs:simpleType>
<!-- 最大值100、最小值0 -->
<xs:maxInclusive value="100"/>
<xs:minInclusive value="0"/>
</xs:restriction>
</xs:simpleType>
<!-- 定义price元素,其类型是price_Type -->
<xs:element name="price" type="price_Type"/>
</xs:schema>
示例二:商场家电
<?xml version="1.0" encoding="GB2312"?>
<e_appliance>
<goods>
<commodity>
<product>电视机</product>
<brand>康佳</brand>
<size>34"</size>
<unit>1</unit>
<price currency="RMB" unit="Yuan">3400.00</price>
</commodity>
<customer>
<name>李素薇</name>
<sex>女</sex>
<address>
<province>云南</province>
<city>昆明</city>
<street>丹霞路234号</street>
<postcode>650031</postcode>
</address>
</customer>
</goods>
<goods>
<commodity>
<product>微波炉</product>
……
</commedity>
<customer>
<name>张绚</name>
……
</customer>
</goods>
<goods>
<commodity>
……
</commodity>
<customer>
……
</customer>
</goods>
</e_appliance>
这是一个比较实际的XML文档,下面是为这个文档设计的XML Schema文档:
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace=" http://www.kmnc.net/namespace/goods"
xmlns:gds ="http://www.kmnc.net/namespace/goods">
<xsd:element name="e_appliance" type="e_applianceType"/>
<xsd:complexType name="e_applianceType ">
<xsd:sequence>
<xsd:element name="goods" type="goodsType"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="goodsType " minOccurs="0" maxOccurs="unbounded">
<xsd:sequence>
<xsd:element name="product" type="xsd:string"/>
<xsd:element name="producer" type="xsd:string"/>
<xsd:element name="size" type="xsd:string"/>
<xsd:element name="unit" type="xsd:integer"/>
<xsd:element name="price" type="priceType"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="commodityType">
<xsd:sequence>
<xsd:element name="product" type="xsd:string"/>
<xsd:element name="brand" type="xsd:string"/>
<xsd:element name="size" type="xsd:string"/>
<xsd:element name="unit" type="xsd:integer"/>
<xsd:element name="price" type="priceType"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="customerType">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="sex" type="xsd:string"/>
<xsd:element name="address" type="addressType"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="priceType">
<xsd:sequence>
<xsd:element name="price">
<xsd:simpleType>
<xsd:restriction base="xsd:decimal">
<xsd:totalDigits value="8">
<xsd:fractionDigits value="2">
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="currency" type="xsd: NMTOKEN"/>
<xsd:attribute name="unit" type="xsd: string"/>
</xsd:complexType>
<xsd:complexType name="addressType">
<xsd:sequence>
<xsd:element name="province" type="xsd:string"/>
<xsd:element name="city" type="xsd:string"/>
<xsd:element name="strreet" type="xsd:string"/>
<xsd:element name="postcode">
<xsd:simpleType name="postcodeType">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\d{6}"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>