使用W3C XML Schema(8)

名称空间

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

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

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

< book  isbn ="0836217462"  xmlns ="http://example.org/ns/books/" >  
.../... 
</ book >  

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

< xs:schema  targetNamespace ="http://example.org/ns/books/"  
xmlns:xs
="http://www.w3.org/2001/XMLSchema"  
xmlns:bk
="http://example.org/ns/books/"  
elementFormDefault
="qualified"  
attributeFormDefault
="unqualified" >  
.../... 
</ xs:schema >

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

既然我们工作于http://example.org/ns/books/名称空间,我们就用它定义(使用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 ="http://example.org/ns/books/"  
xmlns:xml
="http://www.w3.org/XML/1998/namespace"  
xmlns:bk
="http://example.org/ns/books/"  
xmlns:xs
="http://www.w3.org/2001/XMLSchema"  
elementFormDefault
="qualified"  
attributeFormDefault
="qualified" >  
.../... 
</ xs:schema >  

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

< xs:import  namespace ="http://www.w3.org/XML/1998/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 ="http://www.w3.org/1999/xhtml"  
processContents
="skip"  minOccurs ="0"  
maxOccurs
="unbounded" />  
</ xs:sequence >  
</ xs:complexType >  

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

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

 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值