XML 模式:了解命名空间
作者:Rahul Srivastava
迁移到 XML 模式?此命名空间介绍将帮助您了解其比较重要的组件之一。
根据 Namespaces in XML W3C 推荐标准的定义,XML 命名空间 是由国际化资源标识符 (IRI) 标识的 XML 元素和属性集合;该集合通常称作 XML“词汇”。
定义 XML 命名空间的主要动机之一是在使用和重用多个词汇时避免名称冲突。XML 模式用于为 XML 实例创建一个词汇并频繁使用命名空间。因此,正确理解命名空间概念对于从总体上理解 XML 模式和实例验证至关重要。
命名空间在多个方面类似于 Java 中的程序包:
* Java 中的程序包可以包含许多可重用的类和接口。同样,XML 中的命名空间可以有许多可重用的元素和属性。
* 要使用程序包中的类或接口,必须使用程序包名称完全限定该类或接口。同样,要使用命名空间中的元素或属性,必须使用命名空间完全限定该元素或属性。
* Java 程序包可能有一个内部类,该类并不直接位于程序包内部,而是借助它的外围类“属于”该程序包。命名空间也是如此:某些元素或属性可能并不直接在命名空间中,而是借助它的父元素或外围元素而属于命名空间。这是一个传递关系。如果桌子上有一本书,而桌子在地面上,则根据传递关系,这本书位于地面上;尽管这本书并非 直接位于地面上。
因此,可以看出 XML 概念中的命名空间与 Java 中的程序包并无多大区别。这种对比旨在简化对 XML 中命名空间的了解,并帮助您直观认识命名空间的概念。
在本文中,您将了解:
* 命名空间在 XML 中的作用
* 如何声明和使用命名空间
* 默认命名空间与无命名空间之间的区别
* 如何使用 XML 模式创建命名空间,以及
* 命名空间中的限定和非限定元素/属性之间的区别。
声明和应用命名空间
命名空间被声明为元素的属性。并不一定只在根元素声明命名空间;而是可以在 XML 文档中的任何元素中进行声明。声明的命名空间的范围起始于声明该命名空间的元素,并应用于该元素的所有内容,直到被具有相同前缀名称的其他命名空间声明覆盖?其中,元素内容是指该元素的 <opening-tag> 和 </closing-tag> 之间的内容。命名空间声明如下:
<someElement xmlns:pfx="http://www.foo.com" />
在属性 xmlns:pfx 中,xmlns 类似于一个保留字,它只用于声明命名空间。换言之, xmlns 用于绑定命名空间,但其本身并不绑定到任何命名空间。因此,以上示例实际上是将前缀“pfx”与命名空间“http://www.foo.com”绑定在一起。
通常将 XSD 或 XS 用作 XML 模式命名空间的前缀,但具体使用什么前缀完全取决于个人。您可以选择将前缀 ABC 用于 XML 模式命名空间,这是合法的,但没有什么意义。使用有意义的命名空间前缀增强了 XML 文档的清晰性。请注意,前缀只用作占位符,并且必须通过可以识别命名空间的 XML 分析器进行解释才能使用绑定到该前缀的实际命名空间。在 Java 类比中,命名空间绑定可以比作声明一个变量,并且每当引用该变量时,它将被所赋与的值替换。
在上一个命名空间声明示例中,每当在命名空间范围中引用前缀“pfx”时,它将被解释为绑定到实际的命名空间 ( http://www.foo.com):
在 Java 中: String pfx = "http://www.library.com"
在 XML 中: <someElement xmlns:pfx="http://www.foo.com" />
尽管命名空间通常看上去像 URL,但这并不意味着实际声明和使用命名空间时一定要连接到互联网上。实际上,通常将命名空间用作可以在互连网空间中共享词汇和不显示内容的虚拟“容器”。在互连网空间中,URL 是唯一的?因此,您通常选择使用 URL 来唯一标识命名空间。在浏览器中键入命名空间 URL 并不意味着它将显示该命名空间中的所有元素和属性;它只是一个概念。
但这里存在一种误解:尽管 Namespaces in XML W3C 推荐标准声明该命名空间名称应为 IRI,但它对此并无强制规定。因此,我还可以使用以下代码:
<someElement xmlns:pfx=" foo" />
该代码完全合法。
至此应明了,要使用命名空间,首先应使用前缀绑定将其绑定,然后在需要时使用该前缀。但为什么不能从一开始便使用命名空间限定元素或属性呢?首先,由于命名空间(作为 IRI)非常长,因此毫无疑问会使 XML 文档杂乱不堪。第二,也是最重要的,它可能对语法造成严重影响,或者具体一点说,可能对 XML 的生产规则造成严重影响?原因是 IRI 可能包含 XML 1.0 W3C 推荐标准 不允许在 XML 标记中使用的字符。
无效) <http://www.library.com:Book />
有效) <lib:Book xmlns:lib="http://www.library.com" />
下面的元素 Title 和 Author 与命名空间 http://www.library.com 关联:
<?xml version="1.0"?>
<Book xmlns:lib="http://www.library.com">
<lib:Title>Sherlock Holmes</lib:Title>
<lib:Author>Arthur Conan Doyle</lib:Author>
</Book>
在下面的示例中, Sherlock Holmes - III 和 Sherlock Holmes - I 的元素 Title 和 Author 与命名空间 http://www.library.com 关联, Sherlock Holmes - II 的元素 Title 和 Author 与命名空间 http://www.otherlibrary.com 关联。
<?xml version="1.0"?>
<Book xmlns:lib="http://www.library.com">
<lib:Title>Sherlock Holmes - I</lib:Title>
<lib:Author>Arthur Conan Doyle</lib:Author>
<purchase xmlns:lib="http://www.otherlibrary.com">
<lib:Title>Sherlock Holmes - II</lib:Title>
<lib:Author>Arthur Conan Doyle</lib:Author>
</purchase>
<lib:Title>Sherlock Holmes - III</lib:Title>
<lib:Author>Arthur Conan Doyle</lib:Author>
</Book>
Namespaces in XML W3C 推荐标准规定了某些命名空间约束:
1. 以三字母序列 x、m 和 l(采用任何大小写组合)开头的前缀被保留,供 XML 和 XML 相关的规范使用。尽管这不是一个严重错误,但绑定此类前缀并不可取。前缀 xml 根据定义绑定到命名空间名称 http://www.w3.org/XML/1998/namespace。
2. 只有已声明并绑定到命名空间的前缀才能使用。(是否曾经试过在 Java 中使用没有声明的变量?)
以下代码违反了这些约束:
<?xml version="1.0"?>
<Book xmlns:XmlLibrary="http://www.library.com">
<lib:Title>Sherlock Holmes - I</lib:Title>
<lib:Author>Arthur Conan Doyle</lib:Author>
</Book>
[错误]:前缀 lib 未绑定到命名空间。
[不可取]:前缀 XmlLibrary 以“Xml”开头。
单个默认命名空间(而非多个默认命名空间)
重复限定一个要在命名空间中使用的元素或属性可能会非常麻烦。这种情况下,可以声明一个 {默认命名空间}。记住,无论在任何时候都只能存在一个 {默认命名空间}。因此,术语“多个默认命名空间”在实际上是不正确的。
声明一个 {默认命名空间} 意味着,如果 {默认命名空间} 声明范围内的任何元素未使用前缀显式限定,则该元素将被隐式限定。与带前缀的命名空间一样,{默认命名空间} 也可以被覆盖。{默认命名空间} 声明如下:
<someElement
xmlns="http://www.foo.com" />
<?xml version="1.0"?>
<Book xmlns="http://www.library.com">
<Title>Sherlock Holmes</Title>
<Author>Arthur Conan Doyle</Author>
</Book>
这种情况下,元素 Book、Title 和 Author 与命名空间 http://www.library.com 关联。
记住,命名空间的范围起始于声明该命名空间的元素。因此,元素 Book 还与 {默认命名空间}关联,这是因为它没有前缀。
<?xml version="1.0"?>
<Book xmlns="http://www.library.com">
<Title>Sherlock Holmes - I</Title>
<Author>Arthur Conan Doyle</Author>
<purchase xmlns="http://www.otherlibrary.com">
<Title>Sherlock Holmes - II</Title>
<Author>Arthur Conan Doyle</Author>
</purchase>
<Title>Sherlock Holmes - III</Title>
<Author>Arthur Conan Doyle</Author>
</Book>
在以上的示例中, Sherlock Holmes - III 和 Sherlock Holmes - I 的元素 Book、 Title 和 Author 与命名空间 http://www.library.com 关联, Sherlock Holmes - II 的元素 purchase、 Title 和 Author 与命名空间 http://www.otherlibrary.com 关联。
默认命名空间和属性
默认命名空间不应用于属性;因此,要将命名空间应用于属性,必须显式限定该属性。此处的属性 isbn {没有命名空间},而属性 cover 与命名空间 http://www.library.com 关联。
<?xml version="1.0"?>
<Book isbn="1234"
pfx:cover="hard"
xmlns="http://www.library.com"
xmlns:pfx="http://www.library.com">
<Title>Sherlock Holmes</Title>
<Author>Arthur Conan Doyle</Author>
</Book>
取消声明命名空间
Namespaces in XML 1.0 W3C 推荐标准不允许取消绑定已经绑定的前缀,而 Namespaces in XML 1.1 W3C 推荐标准则允许这样做。1.0 没有理由不允许取消绑定,不过该错误已经在 1.1 中得到修正。不必知道此差别,这是因为支持 Namespaces in XML 1.1 的 XML 分析器并不多。
尽管取消绑定带前缀的命名空间有一些差别,但这两个版本均允许您取消绑定或删除已声明的 {默认命名空间}:用其他 {默认命名空间} 声明(覆盖声明中的命名空间为空)覆盖已声明的 {默认命名空间}。取消绑定命名空间与未声明命名空间具有同样的效果。此处的 Sherlock Holmes - III 和 Sherlock Holmes - I 的元素 Book、Title 和 Author 与命名空间 http://www.library.com 关联,而 Sherlock Holmes - II 的元素 purchase、 Title 和 Author {没有命名空间}:
<someElement
xmlns="" />
<?xml version="1.0"?>
<Book xmlns="http://www.library.com">
<Title>Sherlock Holmes - I</Title>
<Author>Arthur Conan Doyle</Author>
<purchase xmlns="">
<Title>Sherlock Holmes - II</Title>
<Author>Arthur Conan Doyle</Author>
</purchase>
<Title>Sherlock Holmes - III</Title>
<Author>Arthur Conan Doyle</Author>
</Book>
此处是根据 XML 1.0 规范中的命名空间取消绑定前缀的无效示例,而根据 XML 1.1 中的命名空间取消绑定前缀则是有效的:
<purchase xmlns:lib="">
从此处开始,前缀 lib 不能在 XML 文档中使用,因为只要您在元素 purchase 的范围内,它就保持未声名状态。当然,您完全可以再次定义它。
无名称空间
如果范围中没有默认命名空间,便不存在命名空间。{默认命名空间} 是使用 xmlns 显式声明的命名空间。如果未使用 xmlns 声明 {默认命名空间},则不能说元素位于 {默认命名空间} 中。这种情况下,我们可以说元素位于 {无命名空间} 中。当已声明的 {默认命名空间} 被取消声明时,也将应用 {无命名空间}。
摘要:
* 声明的命名空间的范围起始于声明该命名空间的元素,并应用于该元素的所有内容,直到被具有相同前缀名称的其他命名空间声明覆盖
* 带前缀的命名空间和 {默认命名空间} 都可以被覆盖。
* 带前缀的命名空间和 {默认命名空间} 都可以被取消声明。
* {默认命名空间} 不直接应用于属性。
* 仅当显式声明 {默认命名空间} 时,该命名空间才存在。如果未声明默认命名空间,则不应使用术语 {默认命名空间}。
* 如果范围中没有默认命名空间,便不存在命名空间。
命名空间和 XML 模式
到目前为止,我们已经了解了如何声明和使用现有命名空间。现在,让我们了解如何创建一个新命名空间,并使用
XML 模式:了解命名空间
最新推荐文章于 2024-08-23 11:37:21 发布