在上面的例子中,元素书本就是一个复杂类型。但是一个简单类型的元素是什么样子的呢?一个简单类型的元素的定义相当简单,比如:
<element name='票据号码' type='positiveInteger'/>
就是关于简单元素票据号码的一个定义。注意这里的"positiveInteger","string"等都是XML Schema中内部已经定义好的变量类型,就象C++中的int,bool,char一样。现在的问题是,如果我要对该变量的范围做一个限定,比如一个我国的邮政编号,都是六位的,而且都是数字,这该如何处理呢?很简单,我们可以从基本的变量类型衍生出来,如下所示:
<element name='邮政编码' type='邮政编码规则'/>
<simpleType name='邮政编码规则' base='string'>
<pattern value='d{6}'/>
</simpleType>
这里就表示元素邮政编码只能是由六个阿拉伯数字组成。它的基本类型是"string"。这里的"pattern"是一个XML Schema的关键字,它表示类型"邮政编码规则",必须和 "value"指定的格式进行匹配。这里'd{6}'表示该元素的值只能由六个数字构成。
再举一个复杂一点的例子,比如我对一件商品设定了一个最低和最高两个价格,我如何对价格这个元素进行表示呢?见下面的代码:
<element name='价格' type='价格规则'/>
<simpleType name="价格规则">
<restriction base="integer">
<minInclusive value="100"/>
<maxInclusive value="999"/>
</restriction>
</simpleType>
这里的价格规则表明元素价格的有效范围只能在100到999之间。它的基本类型为"integer"。注意"minInclusive"和"maxInclusive" 是XML Schema的关键字,它表明了元素价格的上下限范围。
上面我们已经提到,一个复杂类型的元素可以在其中包含其他的元素。比如,一个元素地址,它需要包含公司、组织或者个人的名称,街道,城市,省份和邮政编码等信息。而名称、街道、城市、省份和邮政编码本身也是元素,所以该元素的Schema定义如下:
<element name="地址" type="地址规则">
<complexType name="地址规则">
<sequence>
<element name="name" type="string"/>
<element name="street" type="string"/>
<element name="city" type="string"/>
<element name="state" type="string"/>
<element name="zip" type="decimal"/>
</sequence>
<attribute name="国家" type="NMTOKEN" use="fixed" value="中国"/>
</complexType>
上面这段代码出现了一些新的关键词,"sequence"表示元素地址所包含的这些子元素必须按指定的顺序出现。表示元素地址的属性,其中"NMTOKEN"和在DTD中的定义是一样的。"fixed"的作用可以参照DTD元素属性中的Default这个字段的关于FIXED VALUE的说明。
但是,一个元素中如果子元素可以出现多次该如何定义呢?比如家庭这个元素中,包括人、宠物这两个子元素,而且可以出现多个人,多个宠物。见如下的代码:
<element name="家庭" type="家庭规则">
<complexType name="家庭规则">
<sequence>
<element ref="人" minOccurs="1" maxOccurs="unbounded">
<element ref="宠物" minOccurs="0" maxOccurs="unbounded">
</equence>
</complexType>
里的关键字"minOccurs"表示该元素必须出现的最少次数,"maxOccurs"表示该元素可以出现的最大次数,"unbounded"表示最大次数可以无穷大。考虑到我们大多数人是穷人,有的家庭可能根本没有宠物,元素"宠物"最少出现的次数定义为"0"。默认的情况下,"minOccurs"和"maxOccurs"都等于1。这里还出现了一个关键字"ref",它表示"人"和"宠物"在Schema的其他地方已经进行了定义,我们这里只是引用它一下,类似C++中指针的概念。
下面我们展示一个定义一个订货单格式的XML Schema文档,使大家对Schema的编写有一个基本的认识。实际上,如果你能够顺利的阅读下面的代码,表示你对上面的Schema介绍已经有了一个大概的理解和认识。
<xsd:schema xmlns ="http://www.w3.org/2000/08/XMLSchema">
<element name="订货单" type="订货单类型"/>
<element name="注释" type="string"/>
<complexType name="订货单类型">
<sequence>
<element name="货物目的地" type="地址"/>
<element name="帐单目的地" type="地址"/>
<element ref="注释" minOccurs="0"/>
<element name="所有货物" type="货物类型"/>
</sequence>
<attribute name="订单日期" type="date"/>
</complexType>
<complexType name="地址">
<sequence>
<element name="单位名称" type="xsd:string"/>
<element name="街道" type="string"/>
<element name="城市" type="string"/>
<element name="省份" type="string"/>
<element name="邮政编码" type="decimal"/>
</sequence>
<attribute name="国家" type="NMTOKEN" use="fixed" value="中国"/>
</complexType>
<complexType name="货物类型">
<sequence>
<element name="货物" minOccurs="0" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="产品名称" type="string"/>
<element name="数量">
<simpleType>
<restriction base="positiveInteger">
<maxExclusive value="100"/>
</restriction>
</simpleType>
</element>
<element name="价格" type="decimal"/>
<element ref="注释" minOccurs="0"/>
<element name="装船日期" type="date" minOccurs="0"/>
</sequence>
<attribute name="货物编号" type="SKU"/>
</complexType>
</element>
</sequence>
</complexType>
<!-货物编码,用来唯一标识货物 -->
<simpleType name="SKU">
<restriction base="string">
<pattern value="\d{3}-[A-Z]{2}"/>
</restriction>
</simpleType>
</schema>