XSD 实例
本章将演示如何编写XML模式。您还将了解到模式可以用不同的方式编写.
XML文档
让我们看看这个名为"shiporder.xml"的XML文档:
<?xml version="1.0" encoding="UTF-8"?>
<shiporder orderid="889923"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="shiporder.xsd">
<orderperson>John Smith</orderperson>
<shipto>
<name>Ola Nordmann</name>
<address>Langgt 23</address>
<city>4000 Stavanger</city>
<country>Norway</country>
</shipto>
<item>
<title>Empire Burlesque</title>
<note>Special Edition</note>
<quantity>1</quantity>
<price>10.90</price>
</item>
<item>
<title>Hide your heart</title>
<quantity>1</quantity>
<price>9.90</price>
</item>
</shiporder>
上面的XML文档由根元素"shiporder"组成,它包含一个名为"orderid"的必需属性。"shiporder"元素包含三个不同的子元素:"orderperson", "shipto" and "item"。"item"元素出现两次,它包含一个"title"、一个可选的"note"元素、"quantity"和一个"price"元素。
上一行:xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"告诉XML解析器应该根据模式验证此文档。线路:xsi:noNamespaceSchemaLocation="shiporder.xsd"指定模式驻留的位置(这里它与"shiporder.xml"位于同一文件夹中)。
创建XML架构
现在我们要为上面的XML文档创建一个模式。
我们首先打开一个名为"shiporder.xsd"的新文件。为了创建模式,我们可以简单地遵循XML文档中的结构,并在找到每个元素时定义它。我们将从标准XML声明开始,然后是定义模式的xs:schema元素:
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
...
</xs:schema>
在上面的模式中,我们使用标准名称空间(xs),与此名称空间关联的URI是模式语言定义,其标准值为http://www.w3.org/2001/XMLSchema.
接下来,我们必须定义"shiporder"元素。这个元素有一个属性,它包含其他元素,因此我们认为它是一个复杂类型。"shiporder"元素的子元素由xs:sequence元素包围,该元素定义子元素的有序序列:
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
...
</xs:sequence>
</xs:complexType>
</xs:element>
然后我们必须将"orderperson"元素定义为一个简单类型(因为它不包含任何属性或其他元素)。类型(xs:string)的前缀是与XML架构关联的名称空间前缀,该名称空间前缀指示预定义的架构数据类型:
<xs:element name="orderperson" type="xs:string"/>
接下来,我们必须定义两个复杂类型的元素:"shipto"和"item"。我们首先定义"shipto"元素:
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
通过模式,我们可以定义maxOccurs和minOccurs属性的元素可能出现的次数。maxOccurs指定元素的最大出现次数,minOccurs指定元素的最小出现次数。maxOccurs和minOccurs的默认值都是1!
现在我们可以定义"item"元素了。此元素可以在"shiporder"元素中多次出现。这是通过将"item"元素的maxOccurs属性设置为"unbounded"来指定的,这意味着"item"元素的出现次数可以根据作者的意愿而定。注意,"note"元素是可选的。我们通过将minOccurs属性设置为零来指定这一点:
<xs:element name="item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string" minOccurs="0"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
</xs:element>
我们现在可以声明"shiporder"元素的属性。因为这是必需的属性,所以我们指定use="required"。
注释: 属性声明必须始终排在最后:
<xs:attribute name="orderid" type="xs:string" use="required"/>
下面是名为"shiporder.xsd"的模式文件的完整列表:
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string" minOccurs="0"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="orderid" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
划分模式
以前的设计方法非常简单,但是当文档很复杂时,很难阅读和维护。
下一种设计方法是首先定义所有元素和属性,然后使用ref属性引用它们。
下面是架构文件("shiporder.xsd")的新设计:
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- definition of simple elements -->
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
<!-- definition of attributes -->
<xs:attribute name="orderid" type="xs:string"/>
<!-- definition of complex elements -->
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element ref="name"/>
<xs:element ref="address"/>
<xs:element ref="city"/>
<xs:element ref="country"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="item">
<xs:complexType>
<xs:sequence>
<xs:element ref="title"/>
<xs:element ref="note" minOccurs="0"/>
<xs:element ref="quantity"/>
<xs:element ref="price"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element ref="orderperson"/>
<xs:element ref="shipto"/>
<xs:element ref="item" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute ref="orderid" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
使用命名类型
第三种设计方法定义类或类型,使我们能够重用元素定义。这是通过命名simpleType和complexTypes元素来完成的,然后通过元素的type属性指向它们。
下面是模式文件("shiporder.xsd")的第三种设计:
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="stringtype">
<xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:simpleType name="inttype">
<xs:restriction base="xs:positiveInteger"/>
</xs:simpleType>
<xs:simpleType name="dectype">
<xs:restriction base="xs:decimal"/>
</xs:simpleType>
<xs:simpleType name="orderidtype">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{6}"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="shiptotype">
<xs:sequence>
<xs:element name="name" type="stringtype"/>
<xs:element name="address" type="stringtype"/>
<xs:element name="city" type="stringtype"/>
<xs:element name="country" type="stringtype"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="itemtype">
<xs:sequence>
<xs:element name="title" type="stringtype"/>
<xs:element name="note" type="stringtype" minOccurs="0"/>
<xs:element name="quantity" type="inttype"/>
<xs:element name="price" type="dectype"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="shipordertype">
<xs:sequence>
<xs:element name="orderperson" type="stringtype"/>
<xs:element name="shipto" type="shiptotype"/>
<xs:element name="item" maxOccurs="unbounded" type="itemtype"/>
</xs:sequence>
<xs:attribute name="orderid" type="orderidtype" use="required"/>
</xs:complexType>
<xs:element name="shiporder" type="shipordertype"/>
</xs:schema>
restriction 元素指示数据类型是从w3cxml架构命名空间数据类型派生的。因此,以下片段意味着元素或属性的值必须是字符串值:
<xs:restriction base="xs:string">
限制元素通常用于对元素应用限制。请看上面模式中的以下行:
<xs:simpleType name="orderidtype">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{6}"/>
</xs:restriction>
</xs:simpleType>
这表示元素或属性的值必须是字符串,一行中必须正好有六个字符,并且这些字符必须是0到9之间的数字。