搜索
您的当前位置:首页正文

理解XMLSchema:XMLSchema进阶(I)

来源:二三娱乐
理解XMLSchema:XMLSchema进阶(I)

理解 XML Schema:XML Schema进阶(I)()Chief System Architect2001年12⽉28⽇

内容:本⽂章系列将结合实例对XML Schema,这个⽬前国际标准的XML建模⼯具进⾏⼊门级别的概述,希望⼤家通过本系列的学习能够初步掌握XML Schema的使⽤⽅法和XML Schema⽂档实例的具体语义。本⽂主要针对XML Schema中的命名空间的使⽤做了介绍,围绕命名空间的使⽤,阐述了模式的作⽤域以及命名空间对元素/属性的限定能⼒。在命名空间的限定下,全局元素/属性声明和局部元素/属性声明有着不同的使⽤⽅式和作⽤,介绍了他们在同⼀⽬标命名空间中不同定位,同时就⽬标命名空间的特殊使⽤⽅式作了介绍。

模式⽂档可以被看做⼀个类型定义和元素声明的集合(词汇表),他们的名字被归属于⼀个指定的命名空间,这个命名空间称为⽬标命名空间。⽬标命名空间使我们能够从不同的词汇表中区分定义以及声明。举例来说,⽬标命名空间使我们能够区分在XML Schema 语⾔词汇表中的元素声明和在⼀个其他是么的假定的化学语⾔词汇表中的元素声明。前者使⽬标命名空间\"http://www.w3.org/2001/XMLSchema\"的⼀部分,⽽后者则是另外⼀个命名空间。

当我们想去检查⼀个实例⽂档是否与⼀个或者多个模式⽂档相符合(通过⼀个称为模式校验的处理),我们需要确定在模式定义中声明和定义的哪些元素和属性应该被⽤来检查在实例⽂档中的元素和属性。在这个处理流程中,⽬标命名空间扮演了⼀个⾮常重要的⾓⾊。模式⽂档的作者也有⼏种可选的⽅式来影响元素和属性的标识符如何在实例⽂档中表现。更特别的,通过使⽤明确的或者默认的命名空间前缀,作者能够决定在实例⽂档中出现的局部的声明元素和属性是否必须通过⼀个命名空间的约束验证。模式⽂档的作者就关于局部元素和属性的约束的选择与模式⽂档的结构以及针对实例⽂档的考虑有着很多的牵连,在后⾯的⼩节中我们就其中的⼏个重要⽅⾯进⾏阐述。⽬标命名空间和未限定局部元素/属性

在新版本的定购订单模式⽂档po1.xsd中(相对于前⾯的那篇⽂章XML Schema初步中的po.xsd),我们明确的声明了⼀个⽬标命名空间,并且指明局部定义的元素和属性必须是为⽆限定的。在po1.xsd中的⽬标命名空间为\"http://www.example.com/PO1\",显⽰为属性targetNamespace的值。

局部元素和属性的限定能够在全局指定,这是通过schema元素的⼀对属性,elementFormDefault和attributeFormDefault来实现的。⽽另⼀种⽅式,则是单独地在每个局部声明中使⽤form属性指明。所有类似的属性值可以被设为\"unqualified\"或者\"qualified\",来指出局部声明的元素和属性是否必须为⽆限制的。

在po1.xsd中,通过设定elementFormDefault 和attributeFormDefault为\"unqualified\",我们在全局的级别指明了元素和属性的限定。严格的说,这些设定并不必须,因为这两个属性的默认值就是这个。我们在这⾥声明他们是为了突出这个应⽤⽅式和后⾯我们描述的情形之间的对⽐:

targetNamespace=\"http://www.example.com/PO1\" elementFormDefault=\"unqualified\" attributeFormDefault=\"unqualified\">

Alice Smith

123 Maple Street

Robert Smith 8 Oak Avenue

Hurry, my lawn is going wild!

在这个实例⽂档中声明了⼀个命名空间\"http://www.example.com/PO1\"并且把它和命名空间前缀\"apo:\"相联系。这个前缀是⽤于限定⽂档中的两个元素purchaseOrder 和comment的。这个命名空间和在po1.xsd中模式⽂档的⽬标命名空间是⼀致的。因此⼀个实例⽂档的处理者将知道应当在模式⽂档po1.xsd中查找purchaseOrder和comment的声明。实际上,⽬标命名空间这样命名的原因就是因为对purchaseOrder和comment存在⼀个⽬标的命名空间。在模式⽂档中的⽬标命名空间从⽽控制了在实例⽂档中相应命名空间的校验。

前缀\"apo:\"被应⽤于全局元素purchaseOrder和comment。此外,elementFormDefault和attributeFormDefault要求这个命名空间前缀不是⽤在局部声明的每⼀个元素中,如shipTo、billTo、name和street,并且也不是⽤在任何⼀个属性中(属性都是局部声明的)。purchaseOrder和comment都是全局元素,因为他们整体上都是作为schema元素的直接⼦元素⽽存在的,⽽不是在⼀个特殊类型的内容中声明的。举例来说,在po1.xsd中,purchaseOrder的声明是作为schema元素的⼀个直接⼦元素出现的,然⽽shipTo的声明是作为类型定义PurchaseOrderTYpe的complexType元素的⼦元素出现的。

当局部元素和属性不需要被限定的时候,⼀个实例⽂档的作者需要知道或多或少的关于模式⽂档的细节来能建⽴模式⽂档,从⽽校验实例⽂档。更特殊的,如果作者能够限定只有根元素(如purchaseOrder)是全局的,那么只需要简单的限定根元素。与之相对,作者也许知道所有的元素都是全局声明的,因此实例⽂档中所有的元素都能够被加上命名空间前缀,也许此时会利⽤默认的命名空间声明。另外⼀⽅⾯,如果全局和局部的声明没有统⼀的模式,则作者需要了解模式的细节来正确的对全局的元素和属性加上合适的命名空间前缀。限定的局部元素和属性

虽然在⼀开始,我们可以描述局部元素的限定⽅式,然⽽,元素和属性仍然是可以被要求被独⽴地限定。为了指定所有在模式⽂档中局部声明的元素必须被限定,我们可以通过设置elementFormDefault的值为\"qualified\"来实现:

targetNamespace=\"http://www.example.com/PO1\" elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">

在这个与上述模式⽂档相⼀致的实例⽂档中,我们明确的限定了所有的元素:

Alice Smith

123 Maple Street

Robert Smith 8 Oak Avenue

Hurry, my lawn is going wild!

当然,我们也可以对每个元素使⽤默认命名空间提供的隐含限定来代替明确的显式限定,这就像在下⾯的po2.xml中所显⽰的那样:

Alice Smith

123 Maple Street

Robert Smith 8 Oak Avenue

Hurry, my lawn is going wild!

在po2.xml中,实例⽂档中的所有的元素都属于⼀个命名空间,并且命名空间的语句声明了⼀个默认的命名空间,这个命名空间应⽤于实例⽂档中所有的元素。因此,不需要对任何元素使⽤明确的显式前缀。

属性的限定和元素的限定是⾮常类似的。如果属性是被声明为全局属性或者attibuteFormDefault被设置成\"qualified\"的话,那么属性就必须被限定,在实例⽂档中将以带命名空间前缀的⽅式出现。⼀个具备限定的属性的例⼦是\"xsi:nil\",实际上,需要限定的属性必须明确的加上命名空间前缀,因为XML-Namespaces的说明没有提供关于属性的默认命名空间的机制。在实例⽂档中,属性可以以不带前缀的⽅式出现,属性并⾮⼀定需要要具有限定修饰,⼀般来说,这是典型的应⽤情况。

对于这个限定机制,我们迄今为⽌所描绘的已经涵盖了在特定⽬标命名空间中所有局部元素和属性的声明⽅式。同时,我们也能够通过依靠基本的使⽤form属性声明的⽅式来限定⼀个声明。举例来说,为了需要在实例⽂档中限定局部声明的属性publicKey,我们可以使⽤下⾯的⽅法来声明:

targetNamespace=\"http://www.example.com/PO1\" elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">

注意到在上⾯这个模式⽂档中,对于publicKey属性,我们使⽤了form属性,来代替attributeFormDefault的值。同样,form属性也能够被⽤在元素声明中。下⾯是⼀个与前述模式⽂档相⼀直的实例⽂档的例⼦:

全局声明与局部声明

另外⼀种模式⽂档的撰写风格为:当所有的元素名在⼀个命名空间中是唯⼀的时候,那么就可以创建这样⼀个模式⽂档,在这个模式⽂档中所有的元素都是全局的。这种⽅式和在DTD中使⽤的效果是⼀样。在下⾯的例⼦中,我们修改了最初的po1.xsd,使所有的元素都是全局

中所有的元素都是全局的。这种⽅式和在DTD中使⽤的效果是⼀样。在下⾯的例⼦中,我们修改了最初的po1.xsd,使所有的元素都是全局声明,注意到在这个例⼦⾥⾯我们忽略了elementFormDefault 和 attributeFormDefault属性,这是为了强调突出当只有全局元素和属性声明时,他们的值⽆关痛痒的。

targetNamespace=\"http://www.example.com/PO1\">

这个\"全局\"版的po1.xsd将正确地校验我们的实例⽂档po2.xml,如同我们在前⾯所描述过地,这个⽂档也能够由前⾯那个\"qualified\"版本po1.xsd进⾏校验。换句话说,两个schema⽅法都能够正确验证相同的、带有默认命名空间的实例⽂档。从⼀⽅⾯来看,这两个模式⽂档的设计⽅法是相近的,当然从另⼀⽅⾯来看,这两个模式⽂档的撰写⽅式⼜有着⾮常⼤的差异。特别是,当所有的元素都被声明为全局元素时,就不能利⽤到局部命名的优点。举例来说,对于全局元素⽽⾔,你只能够声明⼀个全局元素\"title\"。然⽽对于局部元素⽽⾔,你能够声明局部元素\"title\",它有⼀个string类型,⽽且它是\"book\"的⼦元素。在同样的模式⽂档中(具有相同的⽬标命名空间),你能够声明第⼆个也叫\"title\"的元素,它可带有枚表值\"Mr Mrs Ms\"。未声明的⽬标命名空间

在前⾯的XML Schema初步这篇⽂章中,我们使⽤没有声明⽬标命名空间的模式⽂档和没有声明命名空间的实例⽂档来阐述了XML

Schema的基本知识。那么此时,⾃然⽽然地会产⽣⼀个问题,在这些模式⽂档和实例⽂档的例⼦⾥⾯⽬标命名空间是什么并且他们引⽤哪⾥?

在购买订单模式⽂档po.xsd中,我们没有为模式⽂档声明⼀个⽬标命名空间,我们也没有声明与模式⽂档⽬标命名空间相关联的命名空间前缀(如上⾯的\"po:\"),⼀般来说,如果有命名空间前缀的话,我们就可以在这个命名空间中查阅到模式⽂档中的类型和元素的定义和声明。如果在模式⽂档不声明⽬标命名空间,那么其结果就是在这个模式⽂档中的定义和声明,如USAddress和purchaseOrder都是没有命名空间修饰限定的引⽤。换句话说,即没有明确的命名空间前缀应⽤于引⽤,同时也没有任何默认的命名空间隐含地应⽤于引⽤。对于当前这个例⼦来说,purchaseOrder元素引⽤了类型PurchaseOrderType定义来实施声明。与之相对,在po.xsd中使⽤的所有XML Schema元素和类型都是通过与XML Schema命名空间相关联的命名空间前缀\"xsd:\"所明确进⾏限定的。

在模式⽂档被设计为没有⽬标命名空间的场合下,我们强烈推荐所有的XML Schema元素和类型通过⼀个和XML Schema命名空间相关联的命名空间前缀如\"xsd:\"来明确实施限定(如在po.xsd中)。我们这样推荐的基本原理是因为如果XML Schema元素和类型默认地与XMLSchema命名空间相联系,⽐如不使⽤命名空间前缀,那么XML Schema类型的引⽤也许不能和⽤户⾃定义类型的引⽤相区别。

使⽤⼀个不带有⽬标命名空间的模式⽂档中的元素声明可以去验证在实例⽂档中没有命名空间前缀限定的元素。也就是说,他们可⽤于验证未被提供命名空间限定的元素,这些元素即没有明确的命名空间前缀,也没有默认的命名空间前缀。所以,为了验证⼀个传统的更本未使⽤命名空间的XML 1.0⽂档,你必须提供⼀个没有⽬标命名空间的模式⽂档。当然,有很多没有使⽤命名空间的XML 1.0⽂档,所以将会有很多没有填写⽬标命名空间的模式⽂档。⼩结

本⽂主要针对XML Schema中的命名空间的使⽤做了介绍,围绕命名空间的使⽤,阐述了模式的作⽤域以及命名空间对元素/属性的限定能⼒。在命名空间的限定下,全局元素/属性声明和局部元素/属性声明有着不同的使⽤⽅式和作⽤,介绍了他们在同⼀⽬标命名空间中不同定位,同时就⽬标命名空间的特殊使⽤⽅式作了介绍。参考资料

参考资料

Web Service 技术/评论⽹站

, Web服务的综合类技术⽹站。, IBM的Web服务技术资源中⼼

, Microsoft的Web服务的开发者资源⽹站Web服务系列技术标准规范

, W3C, 2 May 2001, W3C, 2 May 2001作者简介

柴晓路: 系统架构师, Web Service技术顾问, 成员, UDDI规范中⽂版编辑。专长于Web Service架构、Web Service系列技术以及基于XML的系统集成和数据交换技术,同时对数据库、⾯向对象技术及CSCW等技术⽐较擅长。2001年加⼊,参与了UDDI Specification V2的开发。⽬前作为的主要核⼼成员参与UDDI-China.org的核⼼技术⼯作。2000年获复旦⼤学计算机科学硕⼠学位,曾在国际计算机科学学术会议(ICSC)、亚太区XML技术研讨会(XML Asia/Pacific'99)、中国XML技术研讨会(北京)、计算机科学期刊等各类国际、国内重要会议与期刊上发表论⽂多篇。

因篇幅问题不能全部显示,请点此查看更多更全内容

Top