我们用实际的例子来介绍XML Schema的用法。比如,有这样的XML实例文档:
< ?xml version="1.0" encoding="GB2312"?>
该文档用DTD定义如下:
< !ELEMENT studentlst (student)*>
< !ELEMENT student (name,genda,sid,birthday)>
< !ELEMENT name (#PCDATA)>
< !ELEMENT genda (#PCDATA)>
< !ELEMENT sid (#PCDATA)>
< !ELEMENT birthday (#PCDATA)>
但是其中name和genda、sid等文本元素的数据类型都是统一的字符类型,而事实上我们一般要求对它们有更为严格的限制。比如,要求name仍然为字符类型,而genda为可选的枚举类型,只能取男或女,sid要求是三位的整数类型,并且要求birthday为日期类型。name和birthday的定义比较简单:
<element
name="name"
type="string"
minOccurs="1"
maxOccurs="1/">
< element name="birthday"
type="date"
minOccurs="1"
maxOccurs="1/">
其中string和date类型都是Schema中自带的基本数据类型(Primary Data Type)。minOccurs和maxOccurs是最少和最多出现次数,这里是表示有而且只出现一次。这是最简单的元素声明。在XML Schema中提供两种数据类型:一是我们刚刚接触的基本数据类型或者称为内建数据类型;另外一种是扩展的数据类型,既在基本数据类型基础上用户自己扩展的数据类型。Schema中没有规定性别的类型,也没有直接规定三位整数的数据类型,但是性别是有男、女两种选择的枚举类型;而sid的每位都是非负整数,于是我们可以先定义两类扩展数据类型,然后来限制genda和sid元素。
<simpleType
name="GendaType">
< restriction base="string">
< enumeration value="男"/>
< enumeration value="女"/>
</< font></restriction>
</< font></simpleType>
在定义扩展数据类型时是描述了一个simpleType元素,name属性是该数据类型的名称,数据类型由restriction子元素进行约束,该元素中的base属性是基类型,即它要扩展的基本数据类型。在枚举类型中在restriction的子元素中罗列初可选的数值;而在第二种情况时,通过对各方面(facet)进行规定来定义数据类型,比如length规定该数据类型总共有多少位数,而pattern则通过正则表达式来规定出现的方式。这里的意思是连续出现三位的整数。
用上面定义的数据类型来约束genda和sid的方法和name和birthday元素的声明相同:
<element
name="genda"
type="GendaType"
minOccurs="1"
maxOccurs="1"/>
< element name="sid"
type="SIDType"
minOccurs="1"
maxOccurs="1"/>
有了最基本的四个文本内容的元素,如何定义作为其父元素的student元素呢?由于student元素是由子元素组成的,在Schema中称它位复杂类型的元素。而且其子元素是顺序组成的序列,因此这样声明student元素:
<element
name="student">
< complexType>
< sequence>
< element name="name"
type="string"
minOccurs="1"
maxOccurs="1"/>
< element name="genda"
type="GendaType"
minOccurs="1"
maxOccurs="1"/>
< element name="sid"
type="SIDType"
minOccurs="1"
maxOccurs="1"/>
< element name="birthday"
type="date"
minOccurs="1"
maxOccurs="1"/>
</sequence>
</< font></complexType>
</< font></element>
另外,studentlst元素包含了student元素,并且出现的方式是一个或者多个,或者可以不出现,在Schema中出现的方式可以用miOccurs和maxOccurs来表达:
<element
name="studentlst">
< complexType>
< sequence>
< element name="student"
minOccurs="0"
maxOccurs="unbounded">
< complexType>
< sequence>
< element name="name"
type="string"
minOccurs="1"
maxOccurs="1"/>
< element name="genda"
type="GendaType"
minOccurs="1"
maxOccurs="1"/>
< element name="sid"
type="SIDType"
minOccurs="1"
maxOccurs="1"/>
< element name="birthday"
type="date"
minOccurs="1"
maxOccurs="1"/>
</< font>sequence>
</< font>complexType>
</< font>element>
</< font>sequence>
</< font>complexType>
</< font>element>
最后我们将这些元素和数据类型的声明都包含在schema根元素中:
< ?xml version="1.0"?>
< schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:sl="http://www.xml.org.cn/namespaces/StudentList"
targetNamespace="http://www.xml.org.cn/namespaces/StudentList">
< element name="studentlst">
< complexType>
< sequence>
< element name="student"
minOccurs="0"
maxOccurs="unbounded">
< complexType>
< sequence>
< element name="name"
type="string"
minOccurs="1"
maxOccurs="1"/>
< element name="genda"
type="sl:GendaType"
minOccurs="1"
maxOccurs="1"/>
< element name="sid"
type="sl:SIDType"
minOccurs="1"
maxOccurs="1"/>
< element name="birthday"
type="date" minOccurs="1"
maxOccurs="1"/>
</< font>sequence>
</< font>complexType>
</< font>element>
</< font>sequence>
</< font>complexType>
</< font>element>
< simpleType name="GendaType">
< restriction base="string">
< enumeration value="男"/>
< enumeration value="女"/>
</< font>restriction>
</< font>simpleType>
< simpleType name="SIDType">
< restriction base="string">
< length value="3"/>
< pattern value=""/>
</< font></restriction>
</< font></simpleType>
</< font></schema>