关于名称空间的不同行为 Xpath 和 XQuery
different behaviour Xpath & XQuery regarding namespaces
当我计算这个 XPath 表达式时://superhero[n0:name="Superman"]/n1:name
在这个 xml:
<n0:rootElement xmlns:n0='http://example.com' xmlns:n1='http://example.com'>
<superheroes>
<superhero>
<n0:name>Superman</n0:name>
<n1:name>Clark</n1:name>
</superhero>
<superhero>
<n0:name>Spiderman</n0:name>
<n1:name>Peter</n1:name>
</superhero>
</superheroes>
</n0:rootElement>
使用 XPath 求值器,我得到了预期的结果。
但是当我将它发送到 XQuery 处理器时,我收到一条错误消息,指出
Namespace prefix 'n0' has not been declared
。很奇怪吧?
引起投诉的始终是括号中的前缀(也许它被称为过滤器?)。
我已经使用 http://www.xpathtester.com 来验证 XPath 和 XQuery 解释之间的区别。
它与仅 XPath 的 https://codebeautify.org/Xpath-Tester 一起工作正常。
如果我用 *:
替换 n0:
或 n1:
它适用于 XQuery 处理器,但不适用于 XPath 测试器。
这当然是我为了澄清我的问题而编写的玩具示例。在生产中,我调用了一个外部服务,我认为它是由 Saxon-HE 驱动的。我知道它接受 XQuery,所以我猜它处于 XPath 表达式的“XQuery 模式”。
我对 xml 文件无能为力,因为我是从其他来源收到它的。我可以使用更好的 XQuery 表达式吗?
这是错误还是设计使然?
不同的 XPath 引擎提供不同的方式来绑定表达式中使用的命名空间前缀。我相信有些人会从源文档中获取名称空间绑定。所以这不是不符合标准,而是标准将如何建立原始上下文留给特定处理器。
潜在的问题是您可能希望无论源文档中使用什么命名空间前缀,您的查询都能正常工作。从源文档中获取命名空间绑定对于临时查询很方便,但这意味着对一个文档执行正确操作的查询将因另一个文档而失败。
在 XQuery 中,您可以声明要在查询中使用的任何名称空间:
declare namespace n0 = 'http://example.com';
declare namespace n1 = 'http://example.com';
//superhero[n0:name="Superman"]/n1:name
https://xqueryfiddle.liberty-development.net/bdxZ8S
请参阅 https://www.w3.org/TR/xquery-31/#id-namespace-declaration
中的规范
当我计算这个 XPath 表达式时://superhero[n0:name="Superman"]/n1:name
在这个 xml:
<n0:rootElement xmlns:n0='http://example.com' xmlns:n1='http://example.com'>
<superheroes>
<superhero>
<n0:name>Superman</n0:name>
<n1:name>Clark</n1:name>
</superhero>
<superhero>
<n0:name>Spiderman</n0:name>
<n1:name>Peter</n1:name>
</superhero>
</superheroes>
</n0:rootElement>
使用 XPath 求值器,我得到了预期的结果。
但是当我将它发送到 XQuery 处理器时,我收到一条错误消息,指出
Namespace prefix 'n0' has not been declared
。很奇怪吧?
引起投诉的始终是括号中的前缀(也许它被称为过滤器?)。
我已经使用 http://www.xpathtester.com 来验证 XPath 和 XQuery 解释之间的区别。
它与仅 XPath 的 https://codebeautify.org/Xpath-Tester 一起工作正常。
如果我用 *:
替换 n0:
或 n1:
它适用于 XQuery 处理器,但不适用于 XPath 测试器。
这当然是我为了澄清我的问题而编写的玩具示例。在生产中,我调用了一个外部服务,我认为它是由 Saxon-HE 驱动的。我知道它接受 XQuery,所以我猜它处于 XPath 表达式的“XQuery 模式”。
我对 xml 文件无能为力,因为我是从其他来源收到它的。我可以使用更好的 XQuery 表达式吗?
这是错误还是设计使然?
不同的 XPath 引擎提供不同的方式来绑定表达式中使用的命名空间前缀。我相信有些人会从源文档中获取名称空间绑定。所以这不是不符合标准,而是标准将如何建立原始上下文留给特定处理器。
潜在的问题是您可能希望无论源文档中使用什么命名空间前缀,您的查询都能正常工作。从源文档中获取命名空间绑定对于临时查询很方便,但这意味着对一个文档执行正确操作的查询将因另一个文档而失败。
在 XQuery 中,您可以声明要在查询中使用的任何名称空间:
declare namespace n0 = 'http://example.com';
declare namespace n1 = 'http://example.com';
//superhero[n0:name="Superman"]/n1:name
https://xqueryfiddle.liberty-development.net/bdxZ8S
请参阅 https://www.w3.org/TR/xquery-31/#id-namespace-declaration
中的规范