说我有以下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
属性中给出的类型的名称空间而不是它的前缀?
答案 0 :(得分:3)
在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/']
(但这可能不允许类型在默认命名空间中)