XML Schema主要用来设计XML文档的结构,注意不是格式。有人问怎么不是格式?格式跟结构什么区别?我想搞开发的人都对代码进行格式化过,也就是缩进、字体等等;而我们写的程序实际上也是定义一种结构,它不会因为你是否缩进、采用不同的字体就有所改变吧?很多人哪了不分行的xml文档说用VS的工具格式化一下,确又分不清xml格式跟结构有什么区别,让我难以理解。好了,废话少说,接下来说明下如何使用Schema组件定义xml文档的结构。
一、Schema文档的结构
<?xml version="1.0" encode="utf-8"?> -----xml 声明
<xs:schema targetNamespace="myschema" xmlns="myschema" xmlns:xs=http://www.w3.org/2001/XMLSchema>
<xs:simpleType name="ST1">
<xs:restriction base="xs:int">
<xs:minExclusive value="10"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="E1" type="ST1"/>
<xs:element name="E2" type="ST1"/>
<xs:element name="E3" type="CT1"/>
</xs:schema>
在上面的例子中,定义了一个简单类型,它通过对int类型进行约束而派生,派生之后的ST1为大于10的整数;随后,声明了一个元素E1,元素的文本内容指定为ST1。
在Schema中,对类型的创建称为 定义 ,对元素的创建称为 声明。在使用该schema创建的xml文档中,可能会出现<E1>20</E1>这个元素,在其它使用该schema中的xml文档中,可能出现 <E1>30</E1>,它们都是schema中定义的元素E1的实例,这类似于C编程中声明一个结构,以后可以使用这个结构创建不同的实例。
除了简单类型的定义外,Schema还支持复合类型的定义,如例子中的CT1。随后也声明了一个复合类型的元素E3,E3有子元素E1和E2,而且必须至少有两个E1的实例,在xml应该是类似这样:
<E3>
<E1>20</E1>
<E1>30</E1>
<E2>50</E2>
</E3>
而且sequence也意味着E1必须出现在E2的前面,也就是有顺序关系。
好了,看过前面的例子之后下面总结一下:
1. schema中可以进行类型定义和元素声明(属性也称为声明,后面再说),声明就是把一个名字与已定义的一个数据类型进行关联
2. 类型有简单类型和复合类型之分:简单类型没有子元素(也没有属性),复合类型要么有属性、要么有子元素或者两者都有。
3. 元素的类型是由其关联的数据类型来定
属性声明类似元素声明,只不过它关联的必须是简单类型定义。如我们可以声明下面的属性:
<xs:attribute name="Attr1" type="ST1"/>
注意,我们在这里虽然声明了这个属性,但明明指出哪个元素可以有这个属性。如果我们在定义类型CT1时,指定该类型的元素有这个属性,则像这样定义CT1:
<xs:complexType name="CT1">
<xs:sequence>
<xs:element ref="E1" minOccurs="2" maxOccurs="4"/>
<xs:element ref="E2"/>
</xs:sequence>
<attribute ref="Attr1"/>
<xs:complexType>
从而,E3这个元素就可以出现这个属性了,如
<E3 Attr1="100">
<E1>20</E1>
<E1>30</E1>
<E2>50</E2>
</E3>
在前面的例子中,所有的定义和声明都是xs:schema的子元素,这称为toplevel。只有TopLevel的元素声明才能作为xml文档的根。非toplevel的称为local,它们不能用作xml文档的根。非toplevel的类型定义也不能在其它地方使用,toplevel的则可以。例如ST1是toplevel,那么E1,E2声明都可以使用它。
出现在元素的开始标签与结束标签之间的部分称作元素的内容,元素的内容在类型定义中用内容模型这个概念描述。如果元素只能为文本,如ST1,它就是简单内容。简单类型只有简单内容。复合类型如果只包含文本内容(这时候应该是有属性),那么它就具有简单内容;如果它有子元素(可以没有属性),如CT1,它就是复合内容。
简单类型定义的语法如ST1,比较简单;复合类型比较麻烦,格式如下:
<xs:complexType>
<内容模型定义/>
<属性声明/>
</xs:complexType>
内容模型定义使用组件<simpleContent>/<complexContent>/group/sequence/choice/all这个组件定义,这几个互斥,不能在同一级别同时出现,具体参见相关实现文档。
<xs:complexType name="CT1">
<xs:sequence>
<xs:element ref="E1" minOccurs="2" maxOccurs="4"/>
<xs:element ref="E2"/>
</xs:sequence>
<xs:complexType>