Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6586581
  • 博文数量: 227
  • 博客积分: 10047
  • 博客等级: 上将
  • 技术积分: 6678
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-11 10:33
个人简介

网上的蜘蛛

文章分类

全部博文(227)

文章存档

2010年(19)

2009年(29)

2008年(179)

分类:

2008-04-07 22:53:29

创建可用——并且可复用的Schema

或许编写可复用的schema的第一步是文档化它们。W3C XML Schema 提供了一个XML注释(面向人的)的替代品,以及处理说明(面向机器),可能为支持工具更易于处理。

人 类可读的文档可以用xs:documentation元素定义,而针对应用程序则必须包括在xs:appinfo元素内。它们都必须包含在 xs:annotation元素内,并且接受可选的xml:lang以及source属性和任意的内容类型。source属性是一个URI引用,可被用来 说明说明注释文档的目的或应用程序信息。

xs:annotation元素可以被添加到大多数schema结构的开始处,就如下面的例子那样。appinfo部分演示了如何自定义名称空间和schema可能允许在schema内部一个元素绑定到一个Java类。

<xs:element name="book"> 
<xs:annotation> 
<xs:documentation xml:lang="en"> 
Top level element. 
xs:documentation> 
<xs:documentation xml:lang="fr"> 
Element racine. 
xs:documentation> 
<xs:appinfo source=""> 
<bind xmlns=""> 
<class name="Book"/> 
bind> 
xs:appinfo> 
xs:annotation>

从多个文件组合Schema

对那些希望将一个schema定义在多个文档的人来说——要么切分一个大的schema,要么使用schema代码段的库——W3C XML Schema 提供两种机制来包含外部的schema。

第一种包含机制,xs:include类似于复制并粘贴包含的schema的定义。它是一个包含文件并且它不允许覆盖被包含schema的定义。它可以这样使用:

<xs:include schemaLocation="character.xsd"/>

第二种包含机制,xs:redefine,类似于xs:include,除了它会要求你从包含的schema中重新定义声明。

<xs:redefine schemaLocation="character12.xsd"> 
<xs:simpleType name="nameType"> 
<xs:restriction base="xs:string"> 
<xs:maxLength value="40"/> 
xs:restriction> 
xs:simpleType> 
xs:redefine> 

注意,被重定义的声明必须放在xs:redefine元素中。

我 们已经看到了很多特性,它们可以被一起使用,通过xs:include和xs:redefine去创建schema的库。我们看到了如何引用之前定义好的 元素,如何通过派生定义数据类型并使用它们,如何定义并使用属性组,我们还看到元素好对象的对比、数据类型和类的对比。这里还有另外一个从面向对象设计借 过来的特性,就是可以创建可复用的schema。

抽象类型

这些特性中的第一个,从面向对象设计演变而来的,是替代组。不像我们迄今看到的那些特性,一个替代组不是通过W3C XML Schema元素明确定义的,而是通过引用一个公用的元素(称为head)使用substitutionGroup。 

头元素并不包含任何特定的声明,但必须为全局的。所有的元素在一个替代组内需要有一个类型,要么和头元素同一个类型或者可以从它派生。那么,他们都可以代替头元素使用。在下面的例子中,surname元素可以在name元素被定义的任何地方使用。

<xs:element name="name" type="xs:string"/> 
<xs:element name="surname" type="xs:string" 
substitutionGroup
="name" /> 

现 在,我们也可以定义一个一般的name-elt 元素,它为一个替代组的头元素,其不应直接被使用,而应该使用其的一个派生形式。这是通过声明该元素为抽象的实现的,类似于面向对象语言中的一个抽象类。 下面的例子定义了name-elt为抽象元素,它应该被在引用的地方使用name或surname替代。

<xs:element name="name-elt" type="xs:string" abstract="true"/> 
<xs:element name="name" type="xs:string" 
substitutionGroup
="name-elt"/> 
<xs:element name="surname" type="xs:string" 
substitutionGroup
="name-elt"/>

最终类型

我 们可以,或者另一个方面,希望控制数据类型上的派生。 W3C XML Schema 通过xs:complexType、xs:simpleType或者xs:element上的final属性支持这点。这个属性的值范围 为:restriction, extension 以及#al,通过约束现在扩展或派生。下面的片段代码,举例说明,禁止从characterType 复杂类型的任何派生。

<xs:complexType name="characterType" final="#all"> 
<xs:sequence> 
<xs:element name="name" type="nameType"/> 
<xs:element name="since" type="sinceType"/> 
<xs:element name="qualification" type="descType"/> 
xs:sequence> 
xs:complexType> 

除final外,一个更细粒度的机制是控制简单类型的派生,作用在每个切面(facet)上。这里,这个属性叫做fixed,当它的值设为true的时候,切面(facet)不能进行修改(但其他的切换仍可被增加和修改)。下面的例子防止类型nameType被重定义:

<xs:simpleType name="nameType"> 
<xs:restriction base="xs:string"> 
<xs:maxLength value="32" fixed="true"/> 
xs:restriction> 
xs:simpleType>  
 

名称空间

在W3C XML Schema里的Namespaces 支持是灵活而简单的。它不但允许在实例文档(不像DTD)中使用任何前缀,而且允许你打开Schemas从已知或未知命名空间接受未知的元素和属性。

每个W3C XML Schema文档都通过targetNamespace 属性,绑定到一个特定的名称空间,或者缺少名称空间是因为缺少这样一个属性。每个我们想要定义的命名空间至少需要一个Schema文档(元素和属性没有名称空间也可以被定义)。

截至目前,我们忽略了targetNamespace这个属性,意思就是我们并没有使用名称空间。 要涉足命名空间,先让我们假设我们的例子属于一个简单的名称空间:

<book isbn="0836217462" xmlns=""> 
.../... 
book> 

侵入性最小的方式,就是改写我们的schema,增加一些属性到xs:schema元素里面:

<xs:schema targetNamespace="" 
xmlns:xs
="" 
xmlns:bk
="" 
elementFormDefault
="qualified" 
attributeFormDefault
="unqualified"> 
.../... 
xs:schema>

名称空间的声明扮演着一个很重要的角色。首先(xmlns:xs=)说明下,我们不但选择使用前缀去标识元素以遵守W3C XML Schema的约定,而且我们在目前为止的所有例子中为W3C XML Schema预定义的数据类型都加上了xs前缀。要知道我们可以选择任何其他前缀代替xs。我们甚至可以在这个例子中使用 为我们默认的名称空间,我们本不会为W3C XML Schema元素或者数据类型增加前缀的。

既然我们工作于名 称空间,我们就用它定义(使用bk做前缀)。这意味着我们现在将要对引用加前缀使之成为“对象”(数据类型、元素、属性,……)属于bk:名称空间。再 者,我们本可以选择任何的前缀来标识这个名称空间,或者甚至使用我们默认的名称空间(注意xs:unique, xs:key 以及xs:keyref中使用的 XPath表达式不使用默认名称空间)。

targetNamespace  属性允许你定义独立于名称空间的声明,它的名称空间在本schema中描述。如果你需要引用这个名称空间的对象,这是个很常见的例子,除了targetNamespace之外你还需要提供一个名称空间声明。

最 后的两个属性(elementFormDefault 和attributeFormDefault)是在一个单一的schema中,W3C XML Schema提供的控制设施,无论属性和元素被默认为是否合法的(在一个名称空间内)。合法和非法之间的区别可以通过指定默认值显示,正如上面所述,而且 当定义元素和属性时,加入一个form属性,其值为qualified或unqualified。 

但必须注意的是只有本地元素和属性可被指定为unqualified。所有全局定义的元素和属性必须总是合法(qualified)。

从外部名称空间导入定义

W3C XML Schema不像XSLT和XPath,在一些属性值中使用名称空间前缀来标识数据类型、元素、属性的名称空间。举例来说,我们已经在示例中通篇使用了这 个特性来标识W3C XML Schema 的预定义数据类型。这种机制可以被扩展以从任何其他的名称空间导入定义并在我们的schema中进行复用。

通过三步流程可实现从其他名称空间复用定义。为了声明xml:lang这样的属性,即使对于XML 1.0名称空间这个过程也需要这样完成。首先,必须像往常一样定义名称空间。

<xs:schema targetNamespace="" 
xmlns:xml
="" 
xmlns:bk
="" 
xmlns:xs
="" 
elementFormDefault
="qualified" 
attributeFormDefault
="qualified"> 
.../... 
xs:schema> 

下一步,W3C XML Schema 需要知道符合该名称空间的schema所在位置。可以通过xs:import来实现。

<xs:import namespace="" 
schemaLocation
="myxml.xsd"/> 

W3C XML Schema现在知道它应该从myxml.xsd尝试寻找任何属于该XML名称空间的引用。我们现在就可以使用外部定义了。

<xs:element name="title"> 
<xs:complexType> 
<xs:simpleContent> 
<xs:extension base="xs:string"> 
<xs:attribute ref="xml:lang"/> 
xs:extension> 
xs:simpleContent> 
xs:complexType> 
xs:element> 

你可能感觉奇怪,为什么我们选择从XML名称空间引用xml:lang属性,而不是创建一个xml:lang,我们这样做是因为,引用一个属性(或元素)和引用一个数据类型在关系到名称空间时存在重大区别。

  • 引用一个元素或属性导入了全部内容包括名称和名称空间。
  • 引用一个数据类型仅仅导入其定义,而为你正定义的元素和属性命名,以及使用目标名称空间(如果你的属性或元素为unqualified的话则没有名称空间)的事都要留给你自己去做。

包含未知的元素

要完成这个关于名称空间的部分,我们需要知道我们的schema如何对未知元素开发,沮洳在介绍中约定的那样。这个特性是通过xs:any 和xs:anyAttribute来完成的,它允许分别的包含元素或属性。

举例来说,如果我们希望扩展我们的描述类型为任意的XHTML标签,我们可以这样声明:

<xs:complexType name="descType" mixed="true"> 
<xs:sequence> 
<xs:any namespace="" 
processContents
="skip" minOccurs="0" 
maxOccurs
="unbounded"/> 
xs:sequence> 
xs:complexType> 

xs:anyAttribute 给予了属性相同的功能。

descType 类型现在和内容混合了,并且接受一个任意数字或 名称空间中的任何元素。processContents 属性设为了skip表示告知W3C XML Schema 处理器不进行校验那些本该尝试校验的元素。其他可能的值为,strict 要求校验这些元素,或者lax要求需要时才进行校验。namespace 属性接受一个空格分隔的URI列表,并且特殊的值##local(非合格元素)和##targetNamespace(目标名称空间) 可以包含在该列表中,##other(除了目标以外的其他名称空间)##any (任何名称空间)则可以替代这个URI列表。除了这些提到的值以外不需要任何其他值。

 

W3C XML Schema和实例文档

我们目前已经涵盖了几乎所有的W3C XML Schema的特性,但我们仍需要看一看一些在你的实际工作中可以使用的扩展。为了区别这些另外的特性,一个单独的名称空间 ,通常使用前缀xsi。

xsi:noNamespaceSchemaLocation 和xsi:schemaLocation属性允许你将文档绑定到它的W3C XML Schema上面。连接并不是强制的,并且在合法性校验时亦会给出其他的建议,但是这确实有助于W3C XML Schema工具定位一个schema所在位置。

依赖于使用名称空间,连接可能是:

<book isbn="0836217462"
xmlns:xsi
="-instance"
xsi:noNamespaceSchemaLocation
="file:library.xsd">

或者,类似下面这样(注意具有URL的名称空间的语法以及schema中的URL,在相同的属性中使用空格分隔):

<book isbn="0836217462" 
xmlns
="" 
xmlns:xsi
="-instance" 
xsi:schemaLocation

" file:library.xsd"
> 

其他关于xsi 属性的用法是提供如何将一个元素对应到一个schema的信息。这些属性为xsi:type,它允许你定义元素的简单或复杂类型;以及xsi:nil,允许将nil(null)值赋给一个元素(前提是必须在schema中使用nillable=true属性)。在你的W3C XML Schema中你不需要声明这些属性就可以使用它们。

 

本文译自:http://www.xml.com/pub/a/2000/11/29/schemas/part1.html?page=1

译者:姜晓东(http:
//blog.csdn.net/abigfrog/

联系:QQ:
800736  MSN: j2ee@hotmail.
com

翻译开始结束时间:
2008-3-30 ~ 2008-4-1



使用W3C XML Schema(1)
使用W3C XML Schema(2)

阅读(2734) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~