我总是很难理解这一点:为什么存在XML名称空间?我们什么时候应该使用它们,什么时候不使用?在XML中使用命名空间时,常见的陷阱有哪些?
另外,它们与XML模式有何关系?XSD模式应该始终与名称空间关联吗?
我总是很难理解这一点:为什么存在XML名称空间?我们什么时候应该使用它们,什么时候不使用?在XML中使用命名空间时,常见的陷阱有哪些?
另外,它们与XML模式有何关系?XSD模式应该始终与名称空间关联吗?
Answers:
它们用于允许多种标记语言进行组合,而不必担心元素和属性名称的冲突。
例如,看一下XSLT代码的任何部分,然后思考如果您不使用名称空间而试图编写XSLT,其中输出必须包含“模板”,“ for-each”等元素,将会发生什么情况? 。语法错误,是什么。
我会将建议和陷阱留给比我经验更多的人。
为什么存在XML名称空间?
因为早在1997年,W3C中就有一些很有影响力的人想要他们,并且不会拒绝。即使敢于证明,即使有证明,有更好的方法来解决他们认为的“问题”,他们仍然会发挥自己的影响力,将自己的愿望写到W3C建议中。
到目前为止,围绕XML命名空间的广泛神话中最大的浪费是它们具有技术优势。(这是建议书仅存在的下游影响,因此占据了思维空间-“哎呀,一定有(好的)理由!”,而不是某个地方的遗忘脚注。)
我们什么时候应该使用它们,什么时候不使用?
如果可以帮助,则永远不要使用它们。不幸的是,有兴趣的各方对BAD [*]设备的不懈推广,今天已经形成了规范的簇,这使得几乎不可能不必在某个时候与XML命名空间竞争。因此,即使您自己避开XML命名空间,也将发现从各个方向来看都存在命名空间中的杂乱无章的东西,或者更糟的是,除非您提供这些杂乱的工具集,否则这些工具集只会拒绝工作。
在XML中使用命名空间时,常见的陷阱有哪些?
一个非常常见的陷阱是将Xpath表达式与已将名称空间“默认”的文档一起使用:名称空间必须在表达式中是显式的。另一个问题是在构建文档时“正确”使用它们:它们凭空产生了问题。
另外,它们与XML模式有何关系?XSD模式应该始终与名称空间关联吗?
没有必要的关系,只是XSD Schema规范是在委员会中几乎每个人都对XML命名空间有所了解的时候开发的。因此他们尽了最大努力。尽管如此,仍然可以使用不带名称空间的XSD架构,但这是一个艰难的尝试,因为几乎所有支持XSD架构的工具集都假设您将“想要”使用名称空间。
[*]不良=按设计要求破碎
更新:关于这个非问题非解决方案的旧文章。
几乎与询问“我们为什么要使用Java / C#包?”几乎相同:
恕我直言,最大的陷阱是人机交互解释文档,例如开发代码以处理XML Doc。专注于文档的文字表达而不是解析文档的信息集结果太容易了。
例如以下节点
<a xmlns="uri:foo"/>
<foo:a xmlns:foo="uri:foo"/>
<bar:a xmlns:bar="uri:foo"/>
在语义上都是相同的-但与幼稚的眼睛有很大不同。
第一个示例在开发XPath时产生了一个非常常见的错误-缺少“ a”在名称空间中的事实-因此// a不产生匹配项。(或更糟糕的是,仍然匹配不同名称空间中的节点!)
第三个示例打开了另一个理解上的缺陷-前缀文本在语义上很重要。当使用XPATH解析文档时,只要uri与文档中的URI匹配,我就可以声明我想要匹配的任何前缀。
XML是一种超级语言,这意味着它是任何基于XML的语言的基础(有意义,对吧?)。将XML视为可以用任何语言写任何句子的笔。这完全取决于作者,最好是读者应该知道该语言。
XML名称空间基本上是语言的名称,很像“英语”或“עברית”。我帮助XML文档的接收者解析它并提取其中的信息。
假设我有一家家具厂,而您有一家家具店。您的存储应用程序和我的供应应用程序是完全不相关的,但是当它们通过XML消息进行通信时,消息应易于理解并且双方都可以轻松解析
因此,两个系统都需要了解Schema,该Schema定义了语言语法和约定的限制。将模式视为字典和语法教科书。架构是两个系统都应该知道的文档,每个系统中编写解析代码的人都必须知道该文档,其中包括名称空间的声明。
每个名称空间都被命名为URI,在大多数情况下,它是定义它的架构文档的位置。
当然,并不是每个XML文档都需要一个名称空间,尤其是在不用于将信息传递到远程系统时。例如,当您将对象序列化为XML以持久化在数据库中时。
我们之所以使用命名空间,是因为人们希望在自己的私人爱达荷州使用相同的单词来表示不同的事物。通常,您可以根据上下文确定一个人的意思。在人员数据库中,XML是人员记录。在车辆登记数据库中,XML是车辆登记记录。
两者都保留一个名为“ location”的标签,但是标签对每个标签都具有不同的含义,并且包含不同的字段。
现在,这很酷:但是,如果您需要或希望将两个数据库中的XML存储在同一数据库中怎么办?或者,更有趣的是,如果两个数据库都希望存储来自其他一些常见数据库(例如Accounts数据库)的XML块,该怎么办?
XML名称空间与每个XML标记关联一个URI,以便标记名称本身在其前面有一个url,这是标记名称的一部分(当然,实际的XML文档使用速记方法来做到这一点)。通过仔细选择URI,很容易确定标记名称不会冲突-就像两个位置标记的命名完全不同一样,因此不会造成混淆。另外,两个完全不同的位置标签可以包含来自帐户数据库的内容,并明确声明它们在谈论同一件事。
使所有这些都有用的是XPATH。
通过上面的内容,您可以开始编写XPATH表达式,其内容如下:accounts:account overdue
在此xml中的任意位置找到我的任何部分。或者:accounts:warning message
在此XML特定块中的任意位置找到我的任何项目,其中警告消息是personnel:payment
节点或vehicle:status
节点的子节点(无论深度如何)。
该XPATH表达式可以在XSLT文档中的某处使用,该文档的工作是将XML转换为XHTML或XPDF,以进行显示。
收益是多少?为什么呢 因为您可以搜索XML日志文件,所以将所有过期的邮件都撤出,无论它们出现在什么地方,而不会与其他系统生成的“ message”标签混淆,将它们转换为xhtml,并通过css标签以红色粗体显示:all无需编写程序代码。
例如:XML命名空间示例
用我的话来说:如果您必须对外部公司使用某种XML格式(例如),并且需要在XML文档中提供一些具有相同名称的信息,则需要一个名称空间。例:
<sampleDoc>
<header title="Hello world!">
<items>
<item name="Volvo" color="Blue"/>
</items>
</header>
</sampleDoc>
并且您想要将一些数据合并到此文档中,该文件具有相同的名称,但是具有另一种含义(因此为value),则应使用名称空间:
<sampleDoc>
<header title="Hello world!">
<items>
<item name="Volvo" color="White" my_unique_namespace:color="#FFFFFF"/>
</items>
</header>
</sampleDoc>
当然-您可以更改属性的名称。例如为“ my_unique_color”。在另一个文档中芽,可以再次具有相同名称的属性。因此,如果您具有唯一的名称空间(例如我们的Web域),则可以始终使用相同名称的元素和/或属性,而不会遇到任何问题。