使用 XQuery 检查 XML 文档的名称空间前缀是否在整个文件中重新定义

Use XQuery to check if namespace prefix of an XML document is redefined throughout the file

如何检查 XML 文档是否将相同的命名空间前缀映射到两个不同的命名空间 URI(在不同的点)。

如果满足上述条件,则打印"YES",否则不打印任何内容。

XQuery 的输入可以是任何格式正确的 XML 文件。

我是 XQuery 的新手,我只知道 XPath 1.0 和 2.0 的基础知识

我想解决问题的方法如下: 获取文件中所有名称空间定义的列表,然后检查是否有任何名称在文件中出现两次。

我们要获取的属性列表示例(xmlns:f、xmlns:l、xmlns:d、xmlns:f)。然后如果列表中的任何元素在列表中出现多次,我们需要 return "YES",但我不知道该怎么做。

假设支持带有映射的 XQuery 3.1:

let $bindings := map:merge(
   for $e in //*, $p in in-scope-prefixes($e)
   return map{$p, namespace-uri-for-prefix($p, $e)},
   map{'duplicates':'combine'}
)
return 'YES'[some $k in map:keys($bindings) satisfies count(distinct-values($bindings($k))) gt 1]

未测试。

选项duplicates:combine在这里有点不幸,因为它收集所有绑定到前缀的命名空间,包括重复项,然后稍后消除重复项。下一个 Saxon 版本有一个附加选项,允许您随时删除重复项。

不幸的是,XQuery 不支持命名空间轴。使用支持名称空间轴的 XPath 3.1 处理器,您可以做到

let $bindings := //namespace::*, 
    $prefixes := distinct-values($bindings!name())
return 'YES'[some $p in $prefixes 
             satisfies count(distinct-values(
                         $bindings[name()=$p]/string(.)) gt 1)]