作者:__-霖 | 来源:互联网 | 2023-05-25 12:11
我无法弄清楚XPath本身是否应该受到指责,或者是否是特定的XPath实现使得这一点变得如此困难.问题 - 如何使用MSDeploy Parameters.xml文件更改名称空间中的XML元素? - 是我的灵感.
什么行不通
这是不起作用的基本示例.
XML:
XPath的:
//spring/objects/object[@id='CultureResolver']/@type
XPath查询不返回任何内容,而不是:
Spring.Globalization.Resolvers.SessionCultureResolver, Spring.Web
我期待的工作
我或许天真地希望以下方面有效.
修改后的XML:
修改过的XPath查询:
//spring/spring:objects/spring:object[@id='CultureResolver']/@type
此查询在我使用的在线测试程序中引发错误:
ERROR - Failed to evaluate XPath expression: org.apache.xpath.domapi.XPathStylesheetDOM3Exception: Prefix must resolve to a namespace: spring
什么工作
修改后的XML:
修改过的XPath查询(与我期望的工作相同):
//spring/spring:objects/spring:object[@id='CultureResolver']/@type
为了增加混淆,我发现以下XPath查询适用于原始示例XML(在在线测试器XPath引擎中):
//spring/*[local-name() = 'objects' and namespace-uri() = 'http://www.springframework.net']/*[@id='CultureResolver' and local-name() = 'object' and namespace-uri() = 'http://www.springframework.net']/@type
为什么?
由于命名空间和前缀之间的相互作用,这是否令人困惑?似乎声明没有前缀的命名空间不仅包括该命名空间中的相关元素,而且还包括其所有子节点,因此将其描述为"默认命名空间"(如在相关问题的答案中).声明带前缀的命名空间甚至不包含该命名空间中的相关元素!
是否有某些原因需要将名称空间包含在XML文档的根元素中,而不依赖于特定的XPath实现?
我的XPath引擎
我试图解决的问题涉及Microsoft Web Deploy(MSDeploy)使用的任何XPath引擎.
我也在使用这个在线XPath测试器.
1> Mathias Müll..:
一个有趣且问题很好的问题!据我所知,难点在于XPath引擎处理输入文档中的命名空间声明的方式.
简短的回答
不,这种行为一般与XPath或XPath规范无关.这是由于个别实施.
规格说什么
就XML和XPath规范而言,名称空间可以在任何元素上声明,并且最外层(或"根")元素没有什么特别之处.根元素上的命名空间声明就像任何其他声明一样.
当然还有规则.例如,前缀必须与使用其QName的元素上的名称空间URI相关联,或者与该元素(或该属性)的祖先相关联.所以,以下不是格式良好的XML:
第二个重要规则:默认命名空间只能应用于声明它的元素和所有后代元素.在以下文档中,root
元素根本没有命名空间:
我所讨论的规范是XML,XML命名空间和Xpath规范.
在XPath的实现中会发生什么
现在,如果针对XML文档计算XPath表达式,则此输入文档中存在的所有名称空间声明也必须明确地可用于(声明或"注册")到XPath引擎.
的XPath的一些实施方式通过简单地简化这个重新声明所有命名空间声明是在范围为元素或属性,可作为一个XPath引擎(也参见输入XML文档的这个).
在您的情况下,似乎只考虑在最外层元素上做出的声明.这就是你上一篇XML文档的原因:
works - 因为名称空间声明是在根元素上进行的,并且您从根元素执行XPath表达式.您可以省略默认命名空间的未声明,因为它没有任何效果.
最后,回答你的上一个问题:
是否有某些原因需要将名称空间包含在XML文档的根元素中,而不依赖于特定的XPath实现?
不,没有理由命名空间声明应该在根元素上,除了
在我看来,它们在根元素上声明时更容易找到(非常主观)
如果您想为整个文档声明默认命名空间.在根元素上声明它是使它也适用于根元素的唯一方法
如果根元素本身具有限定名称,即带有前缀.然后,您必须在根元素上声明此前缀和名称空间URI.
如果您的XPath实现自动重新声明范围内的命名空间声明,您当然可以利用它,但有时也会让您感到困惑,正如您所注意到的那样.
@Dabbler你以一种暴露相关信息的方式做了很好的辩论 - XPath引擎实现与XPath规范不同.很高兴知道!为了添加到'参数',我链接的在线测试器似乎也将冒号作为限定名称处理,并且如果它作为前缀解释的内容与命名空间声明不匹配则会抱怨.我怀疑Web Deploy使用的XPath引擎可能是相同的.