| 译文 | XML 命名空间 | |
|---|---|---|
| ( http://www.opendl.com/openxml/w3/TR/xml-names/xml-names-gb.html ) | ||
| 英文 | Namespaces in XML | |
| (http://www.w3.org/TR/REC-xml-names) | ||
| 注意 |
| |
| 译者 |
| |
| 时间 | 初次定稿:2003 02 25 (NZT) | 最后修改: 2003 年 8 月 19 日 (UTC) |
Copyright © 1999 年 W3C® (MIT, INRIA, Keio), All Rights Reserved. W3C liability, trademark, document use, and software licensing rules apply.
XML 命名空间提供了一个通过与由 URI 引用确定的命名空间相联系的简单方法来保证在可扩展标注语言(XML)文档中的元素和属性名字的合法性。
本文档已由 W3C 组织成员和其他感兴趣的各方审阅,并已被组织理事批准为 W3C 建议。这是一个稳定的文档,可以用作参考材料,也可以作为其他文档的标准参考文献。W3C 在建议制定过程中的作用是吸引对本规范的注意并促进它的广泛使用。这能增强 Web 的功能和互操作性。
本规格说明已知的错误列表在 http://www.w3.org/XML/xml-names-19990114-errata。
对本说明的建议可电邮到 xml-names-editor@w3.org.
1 动机和摘要
1.1 关于表示法和使用上的一点注意事项
2 声明命名空间
3 合法名
4 使用合法名
5 命名空间在元素和属性中的运用
5.1 命名空间的范围
5.2 命名空间的缺省情况
5.3 属性的单一性
6 文件的一致
A XML命名空间的内部结构(非标准)
A.1 传统命名空间的不足
A.2 命名空间分区
A.3 扩展元素类型及属性名
A.4 唯一的扩展属性名
B 致谢(非标准)
C 参考书目
让我们设想一个可扩展标注语言(XML)的应用:一个 XML 文件可以包含许多元素和属性(这里亦被称为"标注词汇"),这些元素和属性由多个软件模块定义并使用。这里的一个动机就是模块化,假如有一种这样标注词汇, 既好理解又有可供它使用的软件,那么重复使用这种标注就胜于再创建一个。
像这样包含着多重标注词汇的文件,看上去会造成识别上的问题和冲突。软件模块是设计用于处理这些标签(tags)及属性的需要能够识别这些标签(tags)及属性, 即便在碰到那些本来为其它软件包设计的标注使用相同元素类型或属性名所产生的冲突时也要如此。
基於这些考虑,文件结构中应含有通用名,它的界限延伸到所包含文件范围之外。本文将描述一种实现这点的机制,XML 命名空间。
[定义:一个XML 命名空间是一个命名的汇集,它由 URI 引用[RFC2396]确定,在 XML 文件中做为元素类型和属性名使用]。XML 版本拥有内在结构,而且,从数学上来说不是一个集合,因此, XML 命名空间有别于传统上在计算学科中使用的命名空间。这些将在A XML命名空间的内部结构中讨论。
[定义:假如每个字符都确切相同的话,确定命名空间的 URI 引用可被认为相同。]注意在这一意义上不相同的引用也可能在功能上等同。比如,只存在大小写上不同的 URI 引用,或者有执行不同基准 URIs 的外部实体的 URI 引用。
来自于命名空间的命名可做为合法名 QName 出现,该合法名包含一个把命名分为一个命名空间前缀和一个局域部分的冒号。与 URI 引用成映象的前缀选择了命名空间。统一管理的命名空间和文件自己的命名空间的联合生成了一个通用的唯一的标志符。对前缀范围和缺省也提供相应的机制。
URI 引用可包含一些在命名中所不允许的字符,所以不能直接作为命名空间前缀来使用。因此,命名空间前缀提供了一个引用代理服务。下面将描述的基於属性的语法用来声明命名空间前缀和 URI 引用的关系,支持这种命名空间设计的软件必须识别并按这些声明和前缀行动。
需要注意的是,在本规格说明的产生式中出现的一些非终止符 (nonterminals)不是定义在这里而是在 XML 说明书里[XML]。假如这里定义的非终止符与 XML 说明书中定义的非终止符名字相同,此处的产生式在所有的大小写下与在XML 说明书中相应的匹配的字符串的子集相匹配。
在本规格说明的产生式,NSC 表示“命名空间约束”,是一条所有遵从本规格说明文档必须服从的规则。
注意除 w3.org 之外,所有在例子中使用的域名都是随机选出的并不能认为这些域名有任何重要性。
[定义:命名空间的声明是通过使用一个系列的保留属性。这样的属性的名字必须是xmlns或有xmlns:作为前缀。与其它任何XML属性一样,这些属性可以直接或 缺省方式给定。]
| [1] | NSAttName | ::= | PrefixedAttName | |
| DefaultAttName | ||||
| [2] | PrefixedAttName | ::= | 'xmlns:' NCName | |
| [3] | DefaultAttName | ::= | 'xmlns' | |
| [4] | NCName | ::= | (Letter | '_')
(NCNameChar)* | /* An XML Name, minus the ":" */ |
| [5] | NCNameChar | ::= | Letter
| Digit
| '.' | '-' | '_'
| CombiningChar
| Extender |
[定义:属性的值,是一个URI引用,是识别该命名空间的命名空间名字。]为了满足预期的用途,命名空间的名字应该有唯一和持久的特徵。可直接用于一个模式 (schema,如果存在的话) 的检索不是它的目的,统一资源名(Uniform Resource Names)[RFC2141]是一个在设计句法时以这些用途为目的例子。然而,应该注意到一般的 URLs 能以完成同样用途的方式进行管理。
[定义:如果属性名字与 PrefixedAttName 相匹配, 那么,由 NCName 给定命名空间前缀,该前缀用于将元素及属性名字与在声明所依附的元素的范围的属性值中的命名空间名字联系在一起。]在这样的声明中,命名空间的名字不能为空。
[定义:如果属性名字与 DefaultAttName 相匹配,那么,在属性值中的命名空间名字是那在声明所依附的元素的范围的缺省命名空间。]在这样的缺省声明中,属性值可以为空。缺省命名空间及声明的重载将在5 命名空间在元素和属性中的运用中讨论。
下面是一个命名空间声明的例子,该声明将命名空间前缀 edi 与命名空间名字 http://ecommerce.org/schema相联系:
<x xmlns:edi='http://ecommerce.org/schema'> <!-- 对於"x"元素及内容,前缀 "edi" 与“http://ecommerce.org/schema”捆绑在一起 --> </x> |
以三个字母序列x、m、 l 起头的前缀,包括任何的大小写的组合,保留给 XML 及 XML 相关的规格说明使用。
[定义:在与遵从本规格说明的 XML 文档中,有些给定的名字(以相应于非终止性名字的方式构成)可作为合法名,如下所定义的:
| [6] | QName | ::= |
(Prefix ':')?
LocalPart |
| [7] | Prefix | ::= | NCName |
| [8] | LocalPart | ::= | NCName |
注意前缀只起命名空间占位符的作用。应用程序应使用命名空间名,而不是前缀,来构成有效范围在所含文档之外的名字。
在遵循本规格说明的XML文档中,依照如下规则给定元素类型为合法名:
| [9] | STag | ::= | '<' QName
(S属性)*
S? '>'
|
| [10] | ETag | ::= | '</' QName
S? '>' |
| [11] | EmptyElemTag | ::= | '<' QName
(S
属性)*
S? '/>' |
合法名作为元素类型的例子:
<x xmlns:edi='http://ecommerce.org/schema'> <!-- 元素 'price' 的命名空间是 http://ecommerce.org/schema --> <edi:price units='Euro'>32.18</edi:price> </x> |
| [12] | 属性 | ::= | NSAttName
Eq
AttValue |
| QName Eq
AttValue |
合法名作为属性的例子:
<x xmlns:edi='http://ecommerce.org/schema'> <!-- 属性 'taxClass' 的命名空间是 http://ecommerce.org/schema --> <lineItem edi:taxClass="exempt">Baby food</lineItem> </x> |
除非是 xml 或 xmlns,命名空间前缀必须在使用前缀的元素的开始标签签或其祖先元素(亦即该元素的内容中出现前缀标注)的命名空间声明属性中声明过。根据定义前缀 xml 与命名空间名字 http://www.w3.org/XML/1998/namespace 相捆绑。前缀 xmlns 仅用于命名空间的捆绑,而其本身并不绑定于任何命名空间名字。
在有命名空间声明属性,而该属性不直接出现在 XML 文档实体中,而是由一个外部实体声明缺省属性的情况下,前缀声明的限制可导致操作上的困难。基於无校验验XML处理器的软件不能读这类的声明。许多XML应用程序,大概包括那些对命名空间敏感的程序,都未能调用校验处理器。为使这类的应用程序能正确操作,命名空间必须直接声明,或者,经由缺省属性内部的 DTD 子集声明。
出现在 DTD 中时,元素名字和属性类型同样也以合法名的方式给定:
| [13] | doctypedecl | ::= | '<!DOCTYPE' S
QName (S
ExternalID)?
S? ('['
(markupdecl
| PEReference
| S)*
']'
S?)? '>' |
| [14] | elementdecl | ::= | '<!ELEMENT' S
QName
S
contentspec
S? '>' |
| [15] | cp | ::= | (QName
| choice
| seq)
('?' | '*' | '+')? |
| [16] | Mixed | ::= | '(' S?
'#PCDATA' (S?
'|'
S?
QName)*
S?
')*' |
| '(' S? '#PCDATA' S? ')'
| |||
| [17] | AttlistDecl | ::= | '<!ATTLIST' S
QName
AttDef*
S? '>' |
| [18] | AttDef | ::= | S
(QName | NSAttName)
S AttType
S DefaultDecl |
命名空间声明适用于声明它的元素和该元素内容中 所有的元素,除非被其它具有同样 NSAttName 的命名空间声明所覆盖:
<?xml version="1.0"?>
<!-- 所有在这里的元素都明确地属於HTML的命名空间-->
<html:html xmlns:html='http://www.w3.org/TR/REC-html40'>
<html:head><html:title>Frobnostication</html:title></html:head>
<html:body><html:p>Moved to
<html:a href='http://frob.com'>here.</html:a></html:p></html:body>
</html:html> |
一个元素可有多个命名空间前缀声明作为属性,例如:
<?xml version="1.0"?>
<!-- 两个命名空间始终都有效 -->
<bk:book xmlns:bk='urn:loc.gov:books'
xmlns:isbn='urn:ISBN:0-395-36341-6'>
<bk:title>Cheaper by the Dozen</bk:title>
<isbn:number>1568491379</isbn:number>
</bk:book> |
缺省命名空间适用于声明它的元素(如果那个元素没有命名空间前缀)和所有该元素内容中所有没有前缀的元素。假如在缺省命名空间声明里的 URI 引用为空,那么在声明范围内没有前缀的元素不被认为存在任何命名空间里。注意缺声命名空间不直接适用于属性。
<?xml version="1.0"?>
<!-- elements are in the HTML namespace, in this case by default -->
<html xmlns='http://www.w3.org/TR/REC-html40'>
<head><title>Frobnostication</title></head>
<body><p>Moved to
<a href='http://frob.com'>here</a>.</p></body>
</html> |
<?xml version="1.0"?>
<!-- unprefixed element types are from "books" -->
<book xmlns='urn:loc.gov:books'
xmlns:isbn='urn:ISBN:0-395-36341-6'>
<title>Cheaper by the Dozen</title>
<isbn:number>1568491379</isbn:number>
</book> |
一个较大的命名空间范围的例子:
<?xml version="1.0"?>
<!-- 开始,缺省的命名空间是 "books" -->
<book xmlns='urn:loc.gov:books'
xmlns:isbn='urn:ISBN:0-395-36341-6'>
<title>Cheaper by the Dozen</title>
<isbn:number>1568491379</isbn:number>
<notes>
<!-- 使 HTML 成为某些注释的缺省命名空间 -->
<p xmlns='urn:w3-org-ns:HTML'>
This is a <i>funny</i> book!
</p>
</notes>
</book> |
缺声命名空间可被设为空字符串。在声明范围内效果跟没有缺省命名空间相同。
<?xml version='1.0'?>
<Beers>
<!-- 现在缺省的命名空间是 HTML -->
<table xmlns='http://www.w3.org/TR/REC-html40'>
<th><td>Name</td><td>Origin</td><td>Description</td></th>
<tr>
<!-- 在表格的单元格里无缺省的命名空间 -->
<td><brandName xmlns="">Huntsman</brandName></td>
<td><origin xmlns="">Bath, UK</origin></td>
<td>
<details xmlns=""><class>Bitter</class><hop>Fuggles</hop>
<pro>Wonderful hop, light alcohol, good summer beer</pro>
<con>Fragile; excessive variance pub to pub</con>
</details>
</td>
</tr>
</table>
</Beers> |
在遵从本规格说明的 XML 文档里,没有任何一个标签可包含两个属性,这些属性:
比如,下面每一个 bad 的起始标签都不正确:
<!-- http://www.w3.org is bound to n1 and n2 --> <x xmlns:n1="http://www.w3.org" xmlns:n2="http://www.w3.org" > <bad a="1" a="2" /> <bad n1:a="1" n2:a="2" /> </x> |
<!-- http://www.w3.org is bound to n1 and is the default --> <x xmlns:n1="http://www.w3.org" xmlns="http://www.w3.org" > <good a="1" b="2" /> <good a="1" n1:a="2" /> </x> |
在遵循本说明的XML文档中,元素类型和属性名字必须符合 QName,并且必须满足“命名空间限制”。
如果一个 XML 文档为遵循 XML 的一致符合 XML 的 Name 规定,且所有的标志对符合本说明的 NCName规定, 该 XML 文档则遵循了本说明。
这样的一个文档中,一致的效果表现在:
所有的元素类型和属性名字包含零个或一个冒号。
没有实体名字,PI目标,或符号名字包含任何冒号。
严格地说,属性值声明为类型的 ID,IDREF(S),ENTITY(IES),和 NOTATION 都是名字,且因此不含冒号。然而,属性值的声明类型仅仅对能读标志声明的处理器有用,例如有校验的处理器。这样,除非使用指定的有校验的处理器,否则,不能保证是属性值的内容被检查了并遵循本说明。
在计算学科里,“命名空间”一般指一个命名集合,就是说一个没有重复的集合。可是,以这样一种命名空间来对待用于 XML 标注的名字将很大程度的损害它的可用性。在XML 文档中,这样的名字的基本用途是由诸如询问处理器,式样驱动表达引擎,模式驱动校验器的软件模块来鉴别文档的逻辑结构。考虑如下例子:
<section><title>Book-Signing Event</title> <signing> <author title="Mr" name="Vikram Seth" /> <book title="A Suitable Boy" price="$22.95" /></signing> <signing> <author title="Dr" name="Oliver Sacks" /> <book title="The Island of the Color-Blind" price="$12.95" /></signing> </section> |
title 三次出现在标注之中。 名字自己不能为软件模块提供足够的信息来保证正确的处理。
另一问题存在於使用全局属性,表现在如下例子中,一个用CSS文体来表达的XML文件片断:
<RESERVATION> <NAME HTML:CLASS="largeSansSerif">Layman, A</NAME> <SEAT CLASS="Y" HTML:CLASS="reallyImportant">33B</SEAT> <DEPARTURE>1997-05-24T07:55:00+1</DEPARTURE></RESERVATION> |
CLASS 属性描述票价等级并有值“J”,“Y”, 和“C”, HTML:CLASS 属性用来模仿 HTML 语法的丰富性,并通过生成子类来弥补有限的元素指令表;这两种属性在所有语义层面上都是不同的。
XML 1.0 没有提供内置的办法来声明“全局”属性,只有在通过HTML 应用程序而来的它们的文章描述和解释中,如上述 HTML CLASS 属性的项才为全局的。
为了支持合法名和非合法名都能满足它们预期目的的目标,我们把在 XML 命名空间里出现的名字认定成为属於几种相互无关的传统 (亦即集合结构的) 命名空间中的一种,称之为命名空间分区,这些分区如下:
XML命名空间里的全部元素类型出现在这一分区当中,每个元素有一个唯一的局域部分; 命名空间名字和局域部分的联合唯一地确定了该元素类型。
本分区包含了所有在本命名空间里被定义成全局的属性名。一个全局属性的唯一必要的特徵是它的名字在全局属性分区中为唯一的。本规格说明没有对这样属性的正确使用做出声明。命名空间名字和属性名字的联合唯一地确定了该全局属性。
全部元素类型分区里每一种类型都有相关命名空间,在该命名空间出现该元素的非合法属性名字。这是一个传统命名空间,因为 XML 1.0 禁止在一个元素上属性名字的重复出现。带有元素类型的属性名和命名空间名字的联合唯一地确定了每一种非合法的属性。
在与本规格说明相符的 XML 文件中,所有合法的 (有前缀的) 属性都属於全局属性分区,所有非合法属性都归属於相应的单元素类型分区。
为了便於详细说明规则和做比较,我们在这里定义了以 XML 元素句法表示的在 XML 文档里的元素类型及属性名的扩展形式。
[定义:扩展元素类型被表示为类型 ExpEType 的一个空XML元素。
它要求有一 type 属性,该属性给出类型的局域部分 LocalPart,并且,如果元素是合法的话,则有一可选 ns 的属性来给定它的命名空间名字。]
[定义:扩展属性名被表示为类型 ExpAName 的一个空XML单元。
它要求有一 name 属性,该属性给出名字。如果属性是全局的,它要求有一 ns 来给出属性命名空间名字;否则,它则要求有属性 eltype 来给出所依附的元素的类型,并且,如果知道所依附的元素的话,可选的属性 elns 来给出该元素的命名空间名字。]
在上列例子中作稍微的变化将说明扩展的元素类型及属性名是如何工作的。以下两个片段后紧接着的表格显示了名字的扩展:
<!-- 1 --> <section xmlns='urn:com:books-r-us'>
<!-- 2 --> <title>Book-Signing Event</title>
<!-- 3 --> <signing>
<!-- 4 --> <author title="Mr" name="Vikram Seth" />
<!-- 5 --> <book title="A Suitable Boy" price="$22.95" />
</signing>
</section> |
| Line | Name | Expanded |
| 1 | section | <ExpEType type="section" ns="urn:com:books-r-us" /> |
| 2 | title | <ExpEType type="title" ns="urn:com:books-r-us" /> |
| 3 | signing | <ExpEType type="signing" ns="urn:com:books-r-us" /> |
| 4 | author | <ExpEType type="author" ns="urn:com:books-r-us" /> |
| 4 | title | <ExpAName name='title' eltype="author" elns="urn:com:books-r-us" /> |
| 4 | name | <ExpAName name='name' eltype="author" elns="urn:com:books-r-us" /> |
| 5 | book | <ExpEType type="book" ns="urn:com:books-r-us" /> |
| 5 | title | <ExpAName name='title' eltype="book" elns="urn:com:books-r-us" /> |
| 5 | price | <ExpAName name='price' eltype="book" elns="urn:com:books-r-us" /> |
<!-- 1 --> <RESERVATION xmlns:HTML="http://www.w3.org/TR/REC-html40"> <!-- 2 --> <NAME HTML:CLASS="largeSansSerif">Layman, A</NAME> <!-- 3 --> <SEAT CLASS="Y" HTML:CLASS="largeMonotype">33B</SEAT> <!-- 4 --> <HTML:A HREF='/cgi-bin/ResStatus'>Check Status</HTML:A> <!-- 5 --> <DEPARTURE>1997-05-24T07:55:00+1</DEPARTURE></RESERVATION> |
| 1 | RESERVATION | <ExpEType type="RESERVATION" /> |
| 2 | NAME | <ExpEType type="NAME" /> |
| 2 | HTML:CLASS | <ExpAName name="CLASS" ns=http://www.w3.org/TR/REC-html40 /> |
| 3 | SEAT | <ExpEType type="SEAT" /> |
| 3 | CLASS | <ExpAName name="CLASS" eltype="SEAT"> |
| 3 | HTML:CLASS | <ExpAName name="CLASS" ns="http://www.w3.org/TR/REC-html40" /> |
| 4 | HTML:A | <ExpEType type="A" ns="http://www.w3.org/TR/REC-html40" /> |
| 4 | HREF | <ExpAName name="HREF" eltype="A" elns="http://www.w3.org/TR/REC-html40" /> |
| 5 | DEPARTURE | <ExpEType type="DEPARTURE" /> |
由上面 5.3 属性的单一性描述的限制可以通过要求没有元素有两个属性扩展后的名字是相等的, 也就是说,即有同样的属性-值对,直接地来实现。
本工作是许许多多的人贡献的结果,特别包括万维网协会 XML 工作组,和特别兴趣工作组及 W3C Metadata 活动组。微软的 Charles Frankston 作出了特别珍贵的贡献。