XML 命名空间有啥用?

Posted

技术标签:

【中文标题】XML 命名空间有啥用?【英文标题】:What are XML namespaces for?XML 命名空间有什么用? 【发布时间】:2010-09-12 19:19:52 【问题描述】:

这是我总是觉得很难向别人解释的事情: 为什么存在 XML 命名空间? 我们什么时候应该使用它们,什么时候不应该使用它们? 在 XML 中使用命名空间时常见的陷阱是什么?

另外,它们与 XML 模式有什么关系? XSD 模式是否应该始终与命名空间相关联?

【问题讨论】:

【参考方案1】:

它们用于允许组合多种标记语言,而不必担心元素和属性名称的冲突。

例如,查看任何一点 XSLT 代码,然后想想如果您不使用名称空间并尝试编写输出必须包含“模板”、“for-each”、等等,元素。语法错误,是什么。

我会把建议和陷阱留给比我更有经验的人。

【讨论】:

我很惊讶this fallacy 在 10 到 15 年后仍然占据主导地位。另见this 您是说命名空间是一个好的解决方案是错误的,还是说它们旨在用于消除冲突并且在实践中以这种方式使用(有任何缺点)是错误的?我只断言后者。 我是说 XML 命名空间根本不是一个解决方案。该设备仅“解决”了一些用例,但绝不是全部,而且以排除通用解决方案为代价-实际上存在,甚至在这种愚蠢出现之前就确实存在。而且,顺便说一句,最初它们是“打算”标记出处的,但是当有人指出这已经是一个已解决的问题时,支持者开始移动球门柱,并一直坚持到批评者found better things to do with their time。 @arayq2, ...嗯?使用类似“角色”属性的东西只有在每个人都同意的情况下才有帮助。看看我在生产中使用 XML 命名空间取得良好效果的地方(例如,将模板规则混合到 SVG 模板中,使用命名空间来描述 Inkscape 域中的内容、属于模板引擎的内容等),我很难同意在没有任何相互了解的情况下设计的软件解决方案之间的这种级别的互操作性在没有约定俗成的情况下是可能的。 这在实践中什么时候发生过? (我怀疑几乎从来没有)此外,什么时候真的需要用手写的 xml 来完成?现在大多数 xml 都是生成的,所以它将以 one 文档格式生成。 XML 命名空间是最好的货物崇拜编程。【参考方案2】:

为什么存在 XML 命名空间?

因为,早在 1997 年,W3C 中一些非常有影响力的人想要他们,并且不会拒绝。即使证明了,我敢肯定地说,有更好的方法来解决他们认为自己遇到的“问题”,他们仍然发挥自己的影响力,将自己的愿望写入 W3C 建议。

在围绕 XML 命名空间的广泛神话中,最大的谎言是它们具有技术优势。 (这是建议书的下游效应,它只是存在并因此占据了思维空间——“哎呀,一定有一个(好的)理由!”——而不是在某个地方被遗忘的脚注。)

Much pain, no gain.

我们什么时候应该使用它们,什么时候不应该使用它们?

如果你能提供帮助,你永远不应该使用它们。不幸的是,利益相关方对这种 BAD[*] 设备的不懈推广已经促成了今天的大量规范,这使得在某些时候不必与 XML 命名空间抗衡几乎是不可能的。因此,即使您自己避开了 XML 命名空间,您也会发现包裹着命名空间的杂物从四面八方涌来,或者更糟糕的是,除非您提供这些杂物,否则工具集根本无法工作。

在 XML 中使用命名空间时常见的陷阱是什么?

一个非常常见的缺陷是在将 Xpath 表达式用于“默认”命名空间的文档中:命名空间必须在表达式中显式。另一个问题是在构建文档时“正确”使用它们:they create problems out of thin air。

另外,它们与 XML 模式有什么关系? XSD 模式是否应该始终与命名空间相关联?

没有必要的关系,只是 XSD Schema 规范是在委员会中几乎每个人都对 XML 命名空间咬牙切齿的时候开发的。所以他们尽可能深入地研究它。尽管如此,使用没有命名空间的 XSD 模式是可能的,但这是一个陡峭的上坡路,因为几乎每个支持 XSD 模式的工具集都假定您将“想要”使用命名空间。

[*] BAD = 按设计损坏

更新:An old essay on this non-solution to a non-problem。

【讨论】:

我完全同意这种观点,即使不是完全符合 arayq2 的热情水平。我会澄清我发现的陷阱:1) 1) 命名空间很难摆脱。至少使用我一直在使用的 .Net 工具,从 xml 对象中删除命名空间并非易事。 “一旦你开始走上黑暗的道路,它将永远主宰你的命运” 2)实施方式各不相同; XPath 语法的实现并不总是相同的(很像正则表达式有不同的风格。3)复杂性!如果您不认为任何不必要的复杂性是一个巨大的陷阱,那么请忽略我所说的一切。 @arayq2 90% 的回答只是对一些导致包含命名空间的辩论中的一些个人问题进行了尖锐的讨论。我不喜欢命名空间,也不喜欢你在 W3C 抱怨的任何人,但是 *** 上的答案不是你表达个人感受的地方。保留反对使用命名空间的实际论据,放弃你所说的30种不同的方式,只不过是“我认为命名空间是垃圾”,以及关于一场近20年之战的愤怒文章的链接。【参考方案3】:

这几乎等同于问“我们为什么要为 Java/C# 使用包?”:

可重用性:您可以在不同类型的 xml 文档中重用您定义的一组标签/属性。 模块化:如果您需要在 XML 中添加一些“方面”;向 xml 文档添加命名空间比更改整个 xml 架构定义更简单。 避免污染“主”命名空间:您不必强制解析器使用庞大的架构定义,只需使用您需要的命名空间即可。

【讨论】:

嗨内森。不,这对我来说没有意义。可重用性似乎不适用于这里......我也与命名空间的目的作斗争。在 Xhtml 中,您会在那里找到一个名称空间,我想它的目的是引导浏览器了解您希望如何呈现页面。但是在 SOAP 之类的东西中,消息契约使用了命名空间……我看不出它的用途在哪里。【参考方案4】:

恕我直言,最大的陷阱是人机交互解释文档,例如开发代码来处理 XML 文档。太容易关注文档的文字表达,而不是解析文档的信息集结果。

例如以下节点

<a xmlns="uri:foo"/>
<foo:a xmlns:foo="uri:foo"/>
<bar:a xmlns:bar="uri:foo"/>

在语义上都是相同的——但在天真的眼中却大不相同。

第一个示例在开发 XPath 时产生了一个非常常见的错误——忽略了“a”在命名空间中这一事实——因此 //a 没有产生匹配项。 (或者更糟的是匹配不同命名空间中的节点!)

第三个例子在理解上打开了另一个缺陷——前缀文本在语义上很重要。使用 XPATH 解析文档时,我可以声明我喜欢的任何前缀进行匹配,只要它的 uri 与文档的前缀匹配即可。

【讨论】:

【参考方案5】:

将它们视为元素类型的姓氏。如果您有两个朋友,都叫 Bob,并且您正在谈论其中一个,那么有人可能会问您在谈论哪个 Bob。只说“鲍勃”不是很有帮助,所以你说“鲍勃史密斯”或“鲍勃琼斯”。

元素类型也是如此。有时一个简短的名字是不够的,因为不同的人可以选择相同的名字。因此,您将 URI 作为“姓氏”包含在内,以区分不同的 Bob。

【讨论】:

【参考方案6】:

XML 是一种超级语言,这意味着它是任何基于 XML 的语言的基础(有意义,对吗?)。将 XML 想象成一支可以用任何语言书写任何句子的笔。这一切都取决于作者,最好读者应该知道该语言。

XML namespace 基本上是语言的名称,很像“English”或“עברית”。我帮助 XML 文档的接收者解析它并提取其中的信息。

假设我有一家家具厂,而你有一家家具店。你的存储应用和我的供应应用是完全不相关的,但是当它们通过XML消息进行通信时,消息应该是双方都可以理解和容易解析的

因此,两个系统都需要了解Schema,它定义了语言语法和约定的限制。将模式视为字典和语法教科书。架构是两个系统都应该知道的文档,在每个系统中编写解析代码的人都必须知道,其中包括命名空间的声明。

每个命名空间都被命名为一个 URI,在大多数情况下,它是定义它的架构文档的位置。

当然,并不是每个 XML 文档都需要命名空间,尤其是当它不用于向远程系统传递信息时。例如,当您将对象序列化为 XML 以保存在数据库中时。

【讨论】:

架构不是命名空间有用的必要条件。 好吧,如果没有执行验证,当然可以。但是,命名空间是干什么用的? =8-)【参考方案7】:

我们使用命名空间是因为人们希望在他们自己的私人爱达荷州使用相同的词来表示不同的事物。通常,您可以根据上下文确定一个人的含义。在人事数据库中,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 标签:无需编写任何程序代码

【讨论】:

None of this (esp. about xpaths) is necessarily true. 我对这个答案的理解是,XML的命名空间本质上是一个标签,用来对一组XML元素进行分组或标识?【参考方案8】:

例如:XML Namespaces by Example

用我的话来说:如果您必须为外部公司(例如)使用某种 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”。芽在另一个文件中,可以再有同名的属性。因此,如果您有一个唯一的命名空间(例如我们的网络域),您始终可以使用相同名称的元素和/或属性,而不会出现任何问题。

【讨论】:

过去的爆炸!很久以前,那篇文章就是long thread on the xml-dev list 的跳板。该示例实际上可以显示something else。不幸的是,大多数人都忘记了essential point,同样的盲点一直持续到今天。【参考方案9】:

来自W3 recommendation...

XML 命名空间提供了一种简单的方法来限定可扩展标记语言文档中使用的元素和属性名称,方法是将它们与由 URI 引用标识的命名空间相关联。

【讨论】:

不回答问题。问题是“什么是命名空间”,而不是“请给出定义”。 我认为实际给出您的观点会有所帮助。您可能已经能够给这个人一些阅读 W3 建议所没有的洞察力。【参考方案10】:

命名空间用于消除您在文档中使用的名称的歧义。它还使您能够将短名称绑定到名称空间,然后可以使用该名称空间来引用远程元素或属性。名称空间本身是指定义您在文档中使用的元素和属性的位置。还有很多要知道的,但这就是它的核心。更多信息here。

【讨论】:

以上是关于XML 命名空间有啥用?的主要内容,如果未能解决你的问题,请参考以下文章

Win7系统中的wmi控件是啥?有啥用

c++中Std有啥用

如果没有定义命名空间,一个类会有啥命名空间

XSD:命名空间和默认命名空间有啥区别

命名空间有啥意义? [复制]

django url中的实例命名空间和应用程序命名空间有啥区别?