要求 `xsi:type` 的值是特定命名空间中的类型,而不考虑前缀

requiring the value of `xsi:type` to be a type in a specific namespace regardless of prefix

假设我有以下 XML 文件:

<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:foo="http://foo"
   xsi:type="foo:SomeSubtypeOfA">
    boo
</A>

我希望 XML 实例是派生自 A 的特定类型,例如输入 {http://foo}SomeSubtypeOfA (确实如上例所示)。所以我使用以下 XPath:

/*[@xsi:type='foo:SomeSubtypeOfA']  

... 并检查是否返回节点成功。但是上面的 XPath 是有问题的,因为它依赖于任意前缀,所以它在以下文件上失败:

<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:foo2="http://foo"
   xsi:type="foo2:SomeSubtypeOfA">
    boo
</A>

... 并在以下文件上产生错误匹配:

<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:foo="http://fooX"
   xsi:type="foo:SomeSubtypeOfA">
    boo
</A>

为了消除错误匹配,我可以将 XPath 写成:

/*[namespace::foo[.='http://foo'] and @xsi:type='foo:SomeSubtypeOfA'] 

但这仍然无法说明某些其他前缀绑定到 http://foo 命名空间的可能性。我如何编写上面的 XPath,以便它检查 xsi:type 属性中给定类型的名称空间而不是其前缀?

在 XPath 2.0 中你可以做到

/*[namespace-uri-from-QName(resolve-QName(@xsi:type, .)) = 'http://foo' and local-name-from-QName(resolve-QName(@xsi:type, .)) = 'SomeSubtypeOfA']

在 XPath 1.0 中,您需要做类似

的事情
//*[namespace::*[name()=substring-before(../@xsi:type, ':')] = 'http://foo/']

(但这可能不允许类型在默认命名空间中)