【发布时间】:2010-09-12 19:19:52
【问题描述】:
这是我总是觉得很难向别人解释的事情: 为什么存在 XML 命名空间? 我们什么时候应该使用它们,什么时候不应该使用它们? 在 XML 中使用命名空间时常见的陷阱是什么?
另外,它们与 XML 模式有什么关系? XSD 模式是否应该始终与命名空间相关联?
【问题讨论】:
标签: xml xsd namespaces schema xml-namespaces
这是我总是觉得很难向别人解释的事情: 为什么存在 XML 命名空间? 我们什么时候应该使用它们,什么时候不应该使用它们? 在 XML 中使用命名空间时常见的陷阱是什么?
另外,它们与 XML 模式有什么关系? XSD 模式是否应该始终与命名空间相关联?
【问题讨论】:
标签: xml xsd namespaces schema xml-namespaces
它们用于允许组合多种标记语言,而不必担心元素和属性名称的冲突。
例如,查看任何一点 XSLT 代码,然后想想如果您不使用名称空间并尝试编写输出必须包含“模板”、“for-each”、等等,元素。语法错误,是什么。
我会把建议和陷阱留给比我更有经验的人。
【讨论】:
为什么存在 XML 命名空间?
因为,早在 1997 年,W3C 中一些非常有影响力的人想要他们,并且不会拒绝。即使证明了,我敢肯定地说,有更好的方法来解决他们认为自己遇到的“问题”,他们仍然发挥自己的影响力,将自己的愿望写入 W3C 建议。
在围绕 XML 命名空间的广泛神话中,最大的谎言是它们具有技术优势。 (这是建议书的下游效应,它只是存在并因此占据了思维空间——“哎呀,一定有一个(好的)理由!”——而不是在某个地方被遗忘的脚注。)
我们什么时候应该使用它们,什么时候不应该使用它们?
如果你能提供帮助,你永远不应该使用它们。不幸的是,利益相关方对这种 BAD[*] 设备的不懈推广已经促成了今天的大量规范,这使得在某些时候不必与 XML 命名空间抗衡几乎是不可能的。因此,即使您自己避开了 XML 命名空间,您也会发现包裹着命名空间的杂物从四面八方涌来,或者更糟糕的是,除非您提供这些杂物,否则工具集根本无法工作。
在 XML 中使用命名空间时常见的陷阱是什么?
一个非常常见的缺陷是在将 Xpath 表达式用于“默认”命名空间的文档中:命名空间必须在表达式中显式。另一个问题是在构建文档时“正确”使用它们:they create problems out of thin air。
另外,它们与 XML 模式有什么关系? XSD 模式是否应该始终与命名空间相关联?
没有必要的关系,只是 XSD Schema 规范是在委员会中几乎每个人都对 XML 命名空间咬牙切齿的时候开发的。所以他们尽可能深入地研究它。尽管如此,使用没有命名空间的 XSD 模式是可能的,但这是一个陡峭的上坡路,因为几乎每个支持 XSD 模式的工具集都假定您将“想要”使用命名空间。
[*] BAD = 按设计损坏
【讨论】:
这几乎等同于问“我们为什么要为 Java/C# 使用包?”:
【讨论】:
恕我直言,最大的陷阱是人机交互解释文档,例如开发代码来处理 XML 文档。太容易关注文档的文字表达,而不是解析文档的信息集结果。
例如以下节点
<a xmlns="uri:foo"/>
<foo:a xmlns:foo="uri:foo"/>
<bar:a xmlns:bar="uri:foo"/>
在语义上都是相同的——但在天真的眼中却大不相同。
第一个示例在开发 XPath 时产生了一个非常常见的错误——忽略了“a”在命名空间中这一事实——因此 //a 没有产生匹配项。 (或者更糟的是匹配不同命名空间中的节点!)
第三个例子在理解上打开了另一个缺陷——前缀文本在语义上很重要。使用 XPATH 解析文档时,我可以声明我喜欢的任何前缀进行匹配,只要它的 uri 与文档的前缀匹配即可。
【讨论】:
将它们视为元素类型的姓氏。如果您有两个朋友,都叫 Bob,并且您正在谈论其中一个,那么有人可能会问您在谈论哪个 Bob。只说“鲍勃”不是很有帮助,所以你说“鲍勃史密斯”或“鲍勃琼斯”。
元素类型也是如此。有时一个简短的名字是不够的,因为不同的人可以选择相同的名字。因此,您将 URI 作为“姓氏”包含在内,以区分不同的 Bob。
【讨论】:
XML 是一种超级语言,这意味着它是任何基于 XML 的语言的基础(有意义,对吗?)。将 XML 想象成一支可以用任何语言书写任何句子的笔。这一切都取决于作者,最好读者应该知道该语言。
XML namespace 基本上是语言的名称,很像“English”或“עברית”。我帮助 XML 文档的接收者解析它并提取其中的信息。
假设我有一家家具厂,而你有一家家具店。你的存储应用和我的供应应用是完全不相关的,但是当它们通过XML消息进行通信时,消息应该是双方都可以理解和容易解析的
因此,两个系统都需要了解Schema,它定义了语言语法和约定的限制。将模式视为字典和语法教科书。架构是两个系统都应该知道的文档,在每个系统中编写解析代码的人都必须知道,其中包括命名空间的声明。
每个命名空间都被命名为一个 URI,在大多数情况下,它是定义它的架构文档的位置。
当然,并不是每个 XML 文档都需要命名空间,尤其是当它不用于向远程系统传递信息时。例如,当您将对象序列化为 XML 以保存在数据库中时。
【讨论】:
我们使用命名空间是因为人们希望在他们自己的私人爱达荷州使用相同的词来表示不同的事物。通常,您可以根据上下文确定一个人的含义。在人事数据库中,XML 是人事记录。在车辆登记数据库中,XML 是车辆登记记录。
两者都保留一个名为“位置”的标签,但该标签对每个人的含义不同,并且包含不同的字段。
现在,这很酷:但是如果您需要或想要将两者的 XML 存储在同一个数据库中怎么办?或者,更有趣的是,如果两个数据库都想存储来自其他一些通用数据库(例如:Accounts 数据库)的 XML 块怎么办。
XML 命名空间与每个 XML 标记关联一个 URI,因此标记名称本身前面有一个 url,这是标记名称的一部分(当然,实际的 XML 文档使用简写来做到这一点)。通过仔细选择 URI,很容易确信标签名称不会发生冲突 - 就好像两个位置标签的名称完全不同,所以不会混淆。作为奖励,两个完全不同的位置标签可以包含来自帐户数据库的内容,并明确声明它们在谈论同一件事。
让这一切变得有用的是 XPATH。
通过以上内容,您可以开始编写 XPATH 表达式,例如:在此 xml 中的任何位置找到我的任何 accounts:account overdue 部分。或者:在这个特定的 XML 块中的任何位置找到我的任何 accounts:warning message 项目,其中警告消息是 personnel:payment 节点或 vehicle:status 节点的子节点(无论多么深)。
XPATH 表达式可能在 XSLT 文档中的某处使用,其工作是将 XML 转换为 XHTML 或 XPDF 以供显示。
回报是什么?为什么这样做?因为您可以搜索 XML 日志文件,在任何出现的地方提取所有帐户过期消息,不会将它们与其他系统生成的“消息”标签混淆,将它们转换为 xhtml,并以粗体显示红色通过 css 标签:无需编写任何程序代码。
【讨论】:
用我的话来说:如果您必须为外部公司(例如)使用某种 XML 格式,并且您需要在 XML 文档中提供一些具有相同名称的信息,那么您需要一个命名空间。 示例:
<sampleDoc>
<header title="Hello world!">
<items>
<item name="Volvo" color="Blue"/>
</items>
</header>
</sampleDoc>
并且你想将一些数据合并到这个文件中,它具有相同的名称,但有另一种意义(so value to ),你应该使用命名空间:
<sampleDoc>
<header title="Hello world!">
<items>
<item name="Volvo" color="White" my_unique_namespace:color="#FFFFFF"/>
</items>
</header>
</sampleDoc>
当然 - 您可以更改属性的名称。例如“my_unique_color”。芽在另一个文件中,可以再有同名的属性。因此,如果您有一个唯一的命名空间(例如我们的网络域),您始终可以使用相同名称的元素和/或属性,而不会出现任何问题。
【讨论】:
来自W3 recommendation...
XML 命名空间提供了一种简单的方法来限定可扩展标记语言文档中使用的元素和属性名称,方法是将它们与由 URI 引用标识的命名空间相关联。
【讨论】:
命名空间用于消除您在文档中使用的名称的歧义。它还使您能够将短名称绑定到名称空间,然后可以使用该名称空间来引用远程元素或属性。名称空间本身是指定义您在文档中使用的元素和属性的位置。还有很多要知道的,但这就是它的核心。更多信息here。
【讨论】: