XML Schema 是基于 XML 的 DTD 替换者。
XML Schema 描写 XML 文档的结构。
XML Schema 语言也称作 XMLSchema 定义(XML Schema Definition,XSD)。
实例
<?xml version="1.0"?> <note> <to>George</to> <from>John</from> <heading>Reminder</heading> <body>Don't forget themeeting!</body> </note>
下面这个例子是1个名为"note.xsd" 的 XML Schema 文件,它定义了上面那个 XML 文档的元素:<?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3school.com.cn" xmlns="http://www.w3school.com.cn" elementFormDefault="qualified"> <xs:element name="note"> <xs:complexType> <xs:sequence> <xs:element name="to" type="xs:string"/> <xs:element name="from" type="xs:string"/> <xs:element name="heading"type="xs:string"/> <xs:element name="body" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
规定了默许命名空间的声明。此声明会告知schema 验证器,在此 XML 文档中使用的所有元素都被声明于 "http://www.w3school.com.cn" 这个命名空间。
1旦具有了可用的 XML Schema 实例命名空间:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
您就能够使用 schemaLocation属性了。此属性有两个值。第1个值是需要使用的命名空间。第2个值是供命名空间使用的 XML schema 的位置:
xsi:schemaLocation="http://www.w3school.com.cnnote.xsd"
简易元素
简易元素指那些只包括文本的元素。它不会包括任何其他的元素或属性。文本有很多类型。它可以是 XML Schema 定义中包括的类型中的1种(布尔、字符串、数据等等),或它也能够是您自行定义的定制类型。
定义简易元素的语法:
<xs:element name="xxx" type="yyy"/>
最经常使用的类型是:
xs:string
xs:decimal
xs:integer
xs:boolean
xs:date
xs:time
简易元素的默许值和固定值
<xs:element name="color" type="xs:string" default="red"/> <xs:element name="color" type="xs:string" fixed="red"/>
属性
义属性的语法是:
<xs:attribute name="xxx" type="yyy"/>
可选的和必须的属性
在缺省的情况下,属性是可选的。如需规定属性为必选,请使用 "use" 属性:
<xs:attribute name="lang" type="xs:string" use="required"/>
属性也可设置默许值和固定值,与元素的设置方法相似
限定
对值的限定
下面的例子定义了带有1个限定且名为"age" 的元素。age 的值不能低于 0 或高于 120:
<xs:element name="age"> <xs:simpleType> <xs:restriction base="xs:integer"> <xs:minInclusive value="0"/> <xs:maxInclusive value="120"/> </xs:restriction> </xs:simpleType> </xs:element>
对1组值的限定如需把 XML 元素的内容限制为1组可接受的值,要使用枚举束缚(enumeration constraint)。下面的例子定义了带有1个限定的名为 "car" 的元素。可接受的值只有:Audi, Golf, BMW:
<xs:element name="car"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="Audi"/> <xs:enumeration value="Golf"/> <xs:enumeration value="BMW"/> </xs:restriction> </xs:simpleType> </xs:element>
上面的例子也能够被写为:
<xs:element name="car" type="carType"/> <xs:simpleType name="carType"> <xs:restriction base="xs:string"> <xs:enumeration value="Audi"/> <xs:enumeration value="Golf"/> <xs:enumeration value="BMW"/> </xs:restriction> </xs:simpleType>
注释:在这类情况下,类型"carType" 可被其他元素使用,由于它不是 "car" 元素的组成部份。对1系列值的限定
如需把 XML 元素的内容限制定义为1系列可以使用的数字或字母,我们要使用模式束缚(pattern constraint)。可以使用正则表达式进行束缚。下面的例子定义了带有1个限定的名为 "letter" 的元素。可接受的值只有小写字母 a - z 其中的1个:
<xs:element name="letter"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="[a-z]"/> </xs:restriction> </xs:simpleType> </xs:element>
下1个例子定义了带有1个限定的名为"initials" 的元素。可接受的值是大写字母 A - Z 其中的3个:<xs:element name="initials"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="[A-Z][A-Z][A-Z]"/> </xs:restriction> </xs:simpleType> </xs:element>
数据类型的限定限定 描写
enumeration 定义可接受值的1个列表
fractionDigits 定义所允许的最大的小数位数。必须大于等于0。
length 定义所允许的字符或列表项目的精确数目。必须大于或等于0。
maxExclusive 定义数值的上限。所允许的值必须小于此值。
maxInclusive 定义数值的上限。所允许的值必须小于或等于此值。
maxLength 定义所允许的字符或列表项目的最大数目。必须大于或等于0。
minExclusive 定义数值的下限。所允许的值必须大于此值。
minInclusive 定义数值的下限。所允许的值必须大于或等于此值。
minLength 定义所允许的字符或列表项目的最小数目。必须大于或等于0。
pattern 定义可接受的字符的精确序列。
totalDigits 定义所允许的阿拉伯数字的精确位数。必须大于0。
whiteSpace 定义空白字符(换行、回车、空格和制表符)的处理方式。
复合元素
有4种类型的复合元素:
l 空元素
l 包括其他元素的元素
l 仅包括文本的元素
l 包括元素和文本的元素
在 XML Schema 中,有两种方式来定义复合元素:
1. 通过命名此元素,可直接对"employee"元素进行声明,就像这样:
<xs:element name="employee"> <xs:complexType> <xs:sequence> <xs:element name="firstname"type="xs:string"/> <xs:element name="lastname"type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element>
注:被包围在唆使器 <sequence>中的子元素必须以它们被声明的次序出现2."employee" 元素可使用 type 属性,这个属性的作用是援用要使用的复合类型的名称:
<xs:element name="employee" type="personinfo"/> <xs:complexType name="personinfo"> <xs:sequence> <xs:element name="firstname" type="xs:string"/> <xs:element name="lastname" type="xs:string"/> </xs:sequence> </xs:complexType>
如果使用了上面所描写的方法,那末若干元素都可以使用相同的复合类型,比如这样:<xs:element name="employee" type="personinfo"/> <xs:element name="student" type="personinfo"/> <xs:element name="member" type="personinfo"/> <xs:complexType name="personinfo"> <xs:sequence> <xs:element name="firstname" type="xs:string"/> <xs:element name="lastname" type="xs:string"/> </xs:sequence> </xs:complexType>
也能够在已有的复合元素之上以某个复合元素为基础,然后添加1些元素,就像这样:<xs:element name="employee" type="fullpersoninfo"/> <xs:complexType name="personinfo"> <xs:sequence> <xs:element name="firstname"type="xs:string"/> <xs:element name="lastname"type="xs:string"/> </xs:sequence> </xs:complexType> <xs:complexType name="fullpersoninfo"> <xs:complexContent> <xs:extension base="personinfo"> <xs:sequence> <xs:element name="address"type="xs:string"/> <xs:element name="city"type="xs:string"/> <xs:element name="country"type="xs:string"/> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType>
仅含文本的复合元素可包括文本和属性。此类型仅包括简易的内容(文本和属性),因此我们要向此内容添加 simpleContent 元素。当使用简易内容时,我们就必须在 simpleContent 元素内定义扩大或限定
下面这个例子声明了1个复合类型,其内容被定义为整数值,并且 "shoesize" 元素含着名为 "country" 的属性:
<xs:element name="shoesize"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:integer"> <xs:attribute name="country" type="xs:string" /> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element>
也可为 complexType 元素设定1个名称,并让"shoesize" 元素的 type 属性来援用此名称(通过使用此方法,若干元素都可援用相同的复合类型):<xs:element name="shoesize" type="shoetype"/> <xs:complexType name="shoetype"> <xs:simpleContent> <xs:extension base="xs:integer"> <xs:attribute name="country"type="xs:string" /> </xs:extension> </xs:simpleContent> </xs:complexType>
XML 元素,"letter",含有文本和其他元素:<letter> DearMr.<name>John Smith</name>. Your order<orderid>1032</orderid> will be shippedon <shipdate>2001-07⑴3</shipdate>. </letter>
下面这个 schema 声明了这个"letter" 元素:<xs:element name="letter"> <xs:complexType mixed="true"> <xs:sequence> <xs:element name="name"type="xs:string"/> <xs:element name="orderid"type="xs:positiveInteger"/> <xs:element name="shipdate"type="xs:date"/> </xs:sequence> </xs:complexType> </xs:element>
注释:为了使字符数据可以出现在"letter" 的子元素之间,mixed 属性必须被设置为 "true"。<xs:sequence>标签 (name、orderid 和 shipdate ) 意味着被定义的元素必须顺次出现在"letter" 元素内部。唆使器
有7种唆使器:
Order 唆使器:All Choice Sequence
Occurrence 唆使器:maxOccurs minOccurs
Group 唆使器:Groupname attributeGroup name
All 唆使器
<all> 唆使器规定子元素可以依照任意顺序出现,且每一个子元素必须只出现1次:
<xs:element name="person"> <xs:complexType> <xs:all> <xs:element name="firstname"type="xs:string"/> <xs:element name="lastname"type="xs:string"/> </xs:all> </xs:complexType> </xs:element>
注释:当使用 <all> 唆使器时,可以把<minOccurs> 设置为 0 或 1,而只能把 <maxOccurs> 唆使器设置为 1Choice 唆使器
<choice> 唆使器规定可出现某个子元素或可出现另外1个子元素(非此即彼):
<xs:element name="person"> <xs:complexType> <xs:choice> <xs:element name="employee" type="employee"/> <xs:element name="member" type="member"/> </xs:choice> </xs:complexType> </xs:element>
提示:如需设置子元素出现任意次数,可将<maxOccurs> (稍后会讲授)设置为 unbounded(无穷次)。Sequence 唆使器
<sequence>规定子元素必须依照特定的顺序出现:
<xs:element name="person"> <xs:complexType> <xs:sequence> <xs:element name="firstname" type="xs:string"/> <xs:element name="lastname" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element>
Occurrence 唆使器用于定义某个元素出现的频率。注释:对所有的"Order" 和 "Group" 唆使器(any、all、choice、sequence、group name 和 group reference),其中的 maxOccurs 和 minOccurs 的默许值均为 1。
maxOccurs 唆使器
<maxOccurs>唆使器可规定某个元素可出现的最大次数:
<xs:element name="person"> <xs:complexType> <xs:sequence> <xs:element name="full_name" type="xs:string"/> <xs:element name="child_name" type="xs:string" maxOccurs="10"/> </xs:sequence> </xs:complexType> </xs:element>
上面的例子表明,子元素"child_name" 可在 "person" 元素中最少出现1次(其中 minOccurs 的默许值是 1),最多出现 10 次。minOccurs 唆使器
<minOccurs>唆使器可规定某个元素能够出现的最小次数:
<xs:element name="person"> <xs:complexType> <xs:sequence> <xs:element name="full_name" type="xs:string"/> <xs:element name="child_name" type="xs:string" maxOccurs="10"minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:element>
上面的例子表明,子元素"child_name" 可在 "person" 元素中出现最少0 次,最多出现 10 次。提示:如需使某个元素的出现次数不受限制,请使用maxOccurs="unbounded" 这个声明:
元素组
元素组通过 group 声明进行定义:
<xs:group name="组名称">
...
</xs:group>
必须在 group 声明内部定义1个 all、choice 或 sequence 元素。下面这个例子定义了名为 "persongroup" 的 group,它定义了必须依照精确的顺序出现的1组元素:
<xs:group name="persongroup"> <xs:sequence> <xs:element name="firstname" type="xs:string"/> <xs:element name="lastname" type="xs:string"/> <xs:element name="birthday" type="xs:date"/> </xs:sequence> </xs:group>
在把 group 定义终了以后,就能够在另外一个定义中援用它了:<xs:group name="persongroup"> <xs:sequence> <xs:element name="firstname" type="xs:string"/> <xs:element name="lastname" type="xs:string"/> <xs:element name="birthday" type="xs:date"/> </xs:sequence> </xs:group> <xs:element name="person" type="personinfo"/> <xs:complexType name="personinfo"> <xs:sequence> <xs:group ref="persongroup"/> <xs:element name="country" type="xs:string"/> </xs:sequence> </xs:complexType>
属性组属性组通过 attributeGroup 声明来进行定义:
下面这个例子定义了名为"personattrgroup" 的1个属性组:
<xs:attributeGroup name="personattrgroup"> <xs:attribute name="firstname"type="xs:string"/> <xs:attribute name="lastname"type="xs:string"/> <xs:attribute name="birthday"type="xs:date"/> </xs:attributeGroup>
在已定义终了属性组以后,就能够在另外一个定义中援用它了,就像这样:
<xs:attributeGroup name="personattrgroup"> <xs:attribute name="firstname"type="xs:string"/> <xs:attribute name="lastname"type="xs:string"/> <xs:attribute name="birthday"type="xs:date"/> </xs:attributeGroup> <xs:element name="person"> <xs:complexType> <xs:attributeGroup ref="personattrgroup"/> </xs:complexType> </xs:element>
<any> 元素
<any> 元素使我们有能力通过未被schema 规定的元夙来拓展 XML 文档
下面这个例子是从名为"family.xsd" 的 XML schema 中援用的片断。它展现了1个针对 "person" 元素的声明。通过使用 <any> 元素,我们可以通过任何元素(在 <lastname> 以后)扩大 "person" 的内容:
<xs:element name="person"> <xs:complexType> <xs:sequence> <xs:element name="firstname"type="xs:string"/> <xs:element name="lastname"type="xs:string"/> <xs:any minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:element>
现在,我们希望使用"children" 元夙来扩大 "person" 元素。这此种情况下我们就能够这么做,即便以上这个 schema 的作者没有声明任何 "children" 元素。请看这个 schema 文件,名为"children.xsd":
<?xml version="1.0" encoding="ISO⑻859⑴"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3school.com.cn" xmlns="http://www.w3school.com.cn" elementFormDefault="qualified"> <xs:element name="children"> <xs:complexType> <xs:sequence> <xs:element name="childname"type="xs:string" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
下面这个 XML 文件(名为"Myfamily.xml"),使用了来自两个不同的 schema 中的成份,"family.xsd" 和"children.xsd":<?xml version="1.0" encoding="ISO⑻859⑴"?> <persons xmlns="http://www.microsoft.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:SchemaLocation="http://www.microsoft.comfamily.xsd http://www.w3school.com.cn children.xsd"> <person> <firstname>David</firstname> <lastname>Smith</lastname> <children> <childname>mike</childname> </children> </person> <person> <firstname>Tony</firstname> <lastname>Smith</lastname> </person> </persons>
上面这个 XML 文件是有效的,这是由于schema "family.xsd" 允许我们通过在 "lastname" 元素后的可选元夙来扩大 "person" 元素。<any> 和<anyAttribute> 都可用于制作可扩大的文档,它们使文档有能力包括未在主 XML schema 中声明过的附加元素。
下面的例子是来自名为"family.xsd" 的 XML schema 的1个片断。它为我们展现了针对 "person" 元素的1个声明。通过使用 <anyAttribute> 元素,我们就能够向 "person" 元素添加任意数量的属性:
<xs:element name="person"> <xs:complexType> <xs:sequence> <xs:element name="firstname"type="xs:string"/> <xs:element name="lastname"type="xs:string"/> </xs:sequence> <xs:anyAttribute/> </xs:complexType> </xs:element>
现在,我们希望通过"gender" 属性来扩大 "person" 元素。在这类情况下我们就能够这样做,即便这个 schema 的作者从未声明过任何 "gender" 属性。请看这个 schema 文件,名为"attribute.xsd":
<?xml version="1.0" encoding="ISO⑻859⑴"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3school.com.cn" xmlns="http://www.w3school.com.cn" elementFormDefault="qualified"> <xs:attribute name="gender"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="male|female"/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:schema>
下面这个 XML(名为"Myfamily.xml"),使用了来自不同 schema 的成份,"family.xsd" 和"attribute.xsd":<?xml version="1.0" encoding="ISO⑻859⑴"?> <persons xmlns="http://www.microsoft.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:SchemaLocation="http://www.microsoft.comfamily.xsd http://www.w3school.com.cnattribute.xsd"> <person gender="female"> <firstname>Jane</firstname> <lastname>Smith</lastname> </person> <person gender="male"> <firstname>David</firstname> <lastname>Smith</lastname> </person> </persons>