XML Schema学习笔记(二)

** XML Schema ** ** 学习笔记(二) ** ** **

张小根

1、 关于 include 的用法

include 元素可以将外部的定义和声明引入到文档中,并且作为新 Schema 文档的一部分,但必须注意的一点是,被包含成员的目标命名空间必须和包含的目标命名空间一样。具体写法例子是:

1<include address.xsd="" http:="" schemalocation="“" schemas="" www.andsky.com="" ”=""></include>

2、 如果一个类型是从另一个类型扩展而来的,那么定义为父类型的 element, 在实例文档中,可以通过符合子类型的 element 实例来代替,但必须通过 xsi:type 指明此元素的具体类型。例如:

1<xsd:complextype name="”Person”">
2<xsd:sequence>
3<xsd:element name="”FirstName”" type="”xsd:string”"></xsd:element>
4<xsd:element name="”LastName”" type="”xsd:string”"></xsd:element>
5</xsd:sequence>
6</xsd:complextype>
 1<xsd:complextype name="”Father”">
 2<complexcontent>
 3<xsd:extension base="”Person”">
 4<xsd:sequence>
 5<xsd:element name="”gender”">
 6<xsd:restriction base="”string”">
 7<xsd:enumeration value="”male”"></xsd:enumeration>
 8</xsd:restriction>
 9</xsd:element>
10</xsd:sequence>
11</xsd:extension>
12</complexcontent>
13</xsd:complextype>
1<xsd:element name="”human”" type="”Person”"></xsd:element>

在 XML 实例文档中针对 human 可以是这样的 ( 和面向对象有类似的概念 ):

1<human xsi:type="”Father”">
2<name>xiaogen</name>
3<gender>male</gender>
4</human>

3、 关于置换组

XML Schema 提供了一种机制叫置换组,允许原先定义好的元素被其他元素所替换。更明确的,这个置换组包含了一系列的元素,这个置换组中的每一个元素都被定义为可以替换一个指定的元素,这个指定的元素称为头元素 (Head Element) ,需要注意的是头元素必须作为全局元素声明 , 注意,当一个实例文档包含置换元素时替换元素的类型时从它们的头元素那里派生的,此时并不需要使用我们前面所说的 xsi:type 来识别这些被派生的类型,当定义了置换组之后,并非意味着不能使用头元素,而只能使用这个置换组中的元素,它只是提供了一个允许元素可替换使用的机制。例如:

 1<xsd:schema>
 2<xsd:element name="”comment”" type="”xsd:string”/">
 3<xsd:element name="”shipComment”" substitutiongroup="”comment”" type="”xsd:string”"></xsd:element>
 4<xsd:element name="”customerComment" substituiongroup="”comment”" type="”xsd:string”"></xsd:element>
 5<xsd:element name="”order”">
 6<xsd:complextype>
 7<xsd:element name="”productName”" type="”xsd:string”"></xsd:element>
 8<xsd:element name="”price”" type="”xsd:decimal”"></xsd:element>
 9<xsd:element ref="”comment”"></xsd:element>
10<xsd:element name="”shipDate”" type="”xsd:date”"></xsd:element>
11</xsd:complextype>
12</xsd:element>
13</xsd:element></xsd:schema>

下面是实例文档的一个例子:

1<order>
2<productname>Lapis necklace</productname>
3<price>999</price>
4<shipcomment>Use gold wrap if possible</shipcomment>
5<customercomment>Want this for the holidays!</customercomment>
6<shipdate> 2004-08-15  </shipdate>
7</order>

4、 抽象元素和抽象类型

当一个元素或者类型被声明为“ abstract” 时,那么它就不能在实例文档中使用。当一个元素被声明为 ”abstract” 的时候,元素的置换组的成员必须出现在实例文档中。当一个元素相应的类型被定义声明为 "abstract" 时,所有关联该元素的实例必须使用 "xsi:type" 来指明一个类型,这个类型必须是非抽象的,同时是在定义中声明的抽象类型的派生类型。

一、如将上面的 comment 元素的声明更改成:

1<xsd:element abstract="”true”" name="”comment”" type="”xsd:string”"></xsd:element>

那么上面的 order 实例中就只能包含 customerComment 和 shipComment 才是有效的。

二、如果有下面的类型定义:

`

 1<schema `="" targetnamespace="http://cars.andsky.com/schema" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:target="http://cars.andsky.com/schema"> `
 2
 3` <complextype abstract="true" name="Vehicle"></complextype> `
 4
 5` `
 6
 7` <complextype name="Car"> `
 8
 9` <complexcontent> `
10
11` <extension base="target:Vehicle"></extension> `
12
13` </complexcontent> `
14
15` </complextype> `
16
17` <complextype name="Plane"> `
18
19` <complexcontent> `
20
21` <extension base="target:Vehicle"></extension> `
22
23` </complexcontent> `
24
25` </complextype> `
26
27` <element name="transport" type="target:Vehicle"></element> `
28
29` </schema>

`

  根据以上的定义和声明,下面的实例片断就是不能通过验证的:
1<transport xmlns="http://cars.andsky.com/schema"></transport>

下面经过修改的就可以通过验证了。

`

1<transport `="" cars.andsky.com="" http:="" schema="" xmlns="`" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Car" “="" ”=""></transport>

`

5、 为了阻止类型被派生(包括通过限制派生和通过扩展派生),可以使用 final 来设置(有点和 java 中的 final 的概念类似),其值有三个: restriction,extension,#all 。在模式文件的根元素 schema 元素中有一个可选的 finalDefault 属性,它的值能够取为 final 属性所允许的几个值之一。指定 finalDefault 属性的值的效果等于在模式文档中每个类型定义和元素声明中指定 final 属性,同时其值为 finalDefault 属性的值。如果想阻止前面的 Person 被限制派生,我们需要修改定义为如下:

1<xsd:complextype final="”restriction”" name="”Person”">
2<xsd:sequence>
3<xsd:element name="”FirstName”" type="”xsd:string”"></xsd:element>
4<xsd:element name="”LastName”" type="”xsd:string”"></xsd:element>
5</xsd:sequence>
6</xsd:complextype>

6、 因为在实例文档中与父类型关联的元素(也就是声明为父类型的元素)可以通过派生的子类型来替代,这在 2 中已经有详细的说明和例子。同时, XML Schema 也提供了一种机制来控制派生类型以及置换组在实例文档中使用的机制。这种机制是通过类型的 block 属性来控制的,该属性可以取值为: restriction,extension,#all 。和 final 属性一样,在模式文档的根元素 schema 元素里有一个可选的属性 blockDefault ,它的值为 block 属性所允许的值中的一个。指定 blockDefault 属性的作用等价于在模式文档中为每个类型定义和元素声明指定 block 属性。如在前面例子中我们想阻止在使用 Father 来替代 Person 的话我们需要修改 Person 的定义如下:

1<xsd:complextype block="”extension”" name="”Person”">
2<xsd:sequence>
3<xsd:element name="”FirstName”" type="”xsd:string”"></xsd:element>
4<xsd:element name="”LastName”" type="”xsd:string”"></xsd:element>
5</xsd:sequence>
6</xsd:complextype>

取值为“ extension ”的 block 属性将阻止在实例文档中使用通过扩展的派生类型来替换 Person( 即可以阻止 Father 来替换 Person) ,然而它不会阻止通过约束的派生来替换 Person 。

7、 另外一种派生类型的控制机制是应用于简单类型方面的派生。当定义一个简单类型的时候,我们可以使用 fixed 属性对它的所有定义的参数进行修饰,以阻止这些参数在类型派生中被修改,例如:

1<xsd:simpletype name="”Postcode”">
2<xsd:restriction base="”xsd:string”">
3
4&lt; ` xsd:  ` length value=”  7”  fixed=”true” /&gt;
5
6</xsd:restriction>
7</xsd:simpletype>

当这个简单类型被定义之后,我们能够派生出一个新的邮编类型,在其中我们使用了一个没有在基本类型中固定的参数:

`

1<xsd:simpletype name="UKPostcode"> `
2
3` <xsd:restriction base=" Postcode"> `
4
5` <xsd:pattern value="[A-Z]{2}\d\s\d[A-Z]{2}"></xsd:pattern> `
6
7` </xsd:restriction> `
8
9` </xsd:simpletype>

`

然而,我们不能购派生出一个这样的新的邮编类型:在其中 我们重新定义了任何在基类型中已经被固定 (fixed) 的参数 :

`

 1<xsd:simpletype name="UKPostcode"> `
 2
 3` <xsd:restriction base="ipo:Postcode"> `
 4
 5` <xsd:pattern value="[A-Z]{2}\d\d[A-Z]{2}"></xsd:pattern> `
 6
 7` <!-- illegal attempt to modify facet fixed in base type --> `
 8
 9` <xsd:length fixed="true" value="6"></xsd:length> `
10
11` </xsd:restriction> `
12
13` </xsd:simpletype>

`

Published At
Categories with Web编程
Tagged with
comments powered by Disqus