文章系列是XML Schema的一个从入门到进阶的基本教程。内容主要翻译整理了W3C关于XML Schema的入门级规范:XML Schema Part 0: Primer( http://www.w3.org/TR/xmlschema-0/),同时译者添加了一些个人的编注,并重新整理安排了章节。奉献给大家,旨在让更多的读者来了解,熟悉XML Schema. XML Schema是W3C的推荐标准,于2001年5月正式发布,经过数年的大规模讨论和开发,终于最终奠定下来,使得XML建模有了一个国际标准。XML Schema一确定下来,立刻成为全球公认得首选XML环境下的建模工具,已经基本取代了DTD在XML刚刚成为W3C推荐标准时的地位。由于XML是SGML的一个子集,因此它也继承了SGML世界中用于建模的DTD,当时使用DTD的好处是可以利用大量的在SGML世界中现有的DTD工具,使得开发应用代价维持在一个相对较低的水平。然而,DTD有着不少缺陷:1)DTD是基于正则表达式的,描述能力有限;2) DTD没有数据类型的支持,在大多数应用环境下能力不足;3) DTD的约束定义能力不足,无法对XML实例文档作出更细致的语义限制;4) DTD的结构不够结构化,重用的代价相对较高;5)DTD并非使用XML作为描述手段,而DTD的构建和访问并没有标准的编程接口,无法使用标准的编程方式进行DTD维护。而XML Schema正是针对这些DTD的缺点而设计的,XML Schema是完全使用XML作为描述手段,具有很强的描述能力、扩展能力和处理维护能力。
XML Schema的主要目的是用来定义一类XML文档(一个XML Application)。因此模式的"实例文档"形式常常用来描述一个与特定XML Schema相一致的XML文档。事实上,文档实例和Schema文档都不是必须要以文档的形式存在,他们可以存在以于应用之间传递的字节流的形式存在,或者作为一个数据库记录或者作为XML的"信息项"的集合而存在。然而为了简化入门,我们总是把实例和模式看作文档或者文件,认为它们总以文档实例或是模式文档的形式存在。让我们开始考虑一个在文件po.xml中的实例文档。它描述了一个由家庭产品采购和支付应用生成的购买订单。
po.xml,购买订单的XML实例文档
<?xml version="1.0"?>
<purchaseOrder orderDate="1999-10-20">
<shipTo country="US">
<name>Alice Smith</name>
<street>123 Maple Street</street>
<city>Mill Valley</city>
<state>CA</state>
<zip>90952</zip>
</shipTo>
<billTo country="US">
<name>Robert Smith</name>
<street>8 Oak Avenue</street>
<city>Old Town</city>
<state>PA</state>
<zip>95819</zip>
</billTo>
<comment>Hurry, my lawn is going wild!</comment>
<items>
<item partNum="872-AA">
<productName>Lawnmower</productName>
<quantity>1</quantity>
<USPrice>148.95</USPrice>
<comment>Confirm this is electric</comment>
</item>
<item partNum="926-AA">
<productName>Baby Monitor</productName>
<quantity>1</quantity>
<USPrice>39.98</USPrice>
<shipDate>1999-05-21</shipDate>
</item>
</items>
</purchaseOrder>
购买订单由一个主元素purchaseOrder和子元素shipTo、billTo、comment和items组成。这些子元素(除了comment)也依次包括其他子元素等等。直到一个像USPrice这样的子元素,它包含的是一个数字而不是任何子元素。元素如果包含子元素或者是带有属性则被称为复合类型;反之元素如果仅仅包含数字、字符串或者其他数据等,但不包含任何子元素则称为简单类型。
在实例文档中复合类型和一些简单类型是在购买定单的模式文档中定义。而其他一些标准的简单类型则是作为XML Schema内置的简单类型的指令表的一部分定义的。
在继续查阅购买订单模式文档之前,我们暂时离题来提一下实例文档和购买订单模式文档之间的联系。观察实例文档你可以看到购买订单模式文档并没有被提及。一个实例文档实际上不需要引用模式文档,当然尽管很多实例文档确实引用了,为了使这第一节简单化,我们一开始选择不引用。并且假设任何实例文档的处理器即使从实例文档中得不到任何信息,也能够包含购买订单模式文档的处理。在后面的章节,我们将介绍联系实例文档和模式文档的外部机制。
购买订单模式文档
购买订单模式文档包含在文件po.xsd中:
po.xsd,购买订单的Schema文档
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Purchase order schema for Example.com.
Copyright 2000 Example.com. All rights reserved.
</xsd:documentation>
</xsd:annotation>
<xsd:element name="purchaseOrder" type="PurchaseOrderType"/>
<xsd:element name="comment" type="xsd:string"/>
<xsd:complexType name="PurchaseOrderType">
<xsd:sequence>
<xsd:element name="shipTo" type="USAddress"/>
<xsd:element name="billTo" type="USAddress"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="items" type="Items"/>
</xsd:sequence>
<xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>
<xsd:complexType name="USAddress">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="street" type="xsd:string"/>
<xsd:element name="city" type="xsd:string"/>
<xsd:element name="state" type="xsd:string"/>
<xsd:element name="zip" type="xsd:decimal"/>
</xsd:sequence>
<xsd:attribute name="country" type="xsd:NMTOKEN"
fixed="US"/>
</xsd:complexType>
<xsd:complexType name="Items">
<xsd:sequence>
<xsd:element name="item" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="productName" type="xsd:string"/>
<xsd:element name="quantity">
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:maxExclusive value="100"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="USPrice" type="xsd:decimal"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="shipDate" type="xsd:date" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="partNum" type="SKU" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<!-- Stock Keeping Unit, a code for identifying products -->
<xsd:simpleType name="SKU">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\d{3}-[A-Z]{2}"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
购买订单模式文档由一个schema元素和一系列子元素组成,大多数子元素为element, complexType, 和simpleType,这些决定了在实例文档中的元素的表现方式和内容。
通过出现在schema元素中的命名空间声明xmlns:xsd="http://www.w3.org/2001/XMLSchema",在模式文档中的每一个元素都有一个与XML Schema命名空间相联系的命名空间前缀"xsd:".尽管任何前缀都能够被使用,但是,前缀"xsd:"被约定用于表示XML Schema命名空间。通过使用同样的前缀,这样同样的关联也出现在内置的简单类型的名字中。例如,xsd:string.这种形式的关联的目的是用来标识元素和简单类型是属于XML Schema语言的词汇表而不是模式文档作者自己的词汇表。为了在这里清楚表示,我们仅提及元素的名字和简单类型(如simpleType)而忽略了它们的前缀"xsd:".