我正在使用XPATH 1.0从XML文档中获取某些节点,该文档在根目录和具有属性的节点上使用默认命名空间。 attributeFormDefault = "qualified"
在架构上设置。
<Transaction xmlns="http://example.com/transaction">
<someElement/>
<collection>
<value p0:Name="SomeName" xmlns:p0="http://example.com/transaction">some value</value>
<value p1:Name="SomeOtherName" xmlns:p1="http://example.com/transaction">some other value</value>
</collection>
<differentCollection>
<value p2:Name="SomeName" xmlns:p2="http://example.com/transaction">not this one</value>
</differentCollection>
</Transaction>
我的目标是获取/Transaction/collection/value[@Name='SomeName']
节点。
到目前为止我找到的唯一解决方案似乎有点宽泛:
//*[@*='SomeName']
我还可以使用以下方法获取<value>
个节点的整个集合:
//*[local-name()='value']
考虑到命名空间限制,是否有更清晰,更精确的方式获取我追求的节点?第三方javascript库不是一个选项。
修改
感谢您的快速回复。我将在此处注意到,通过添加默认名称空间前缀,解决了xpath查询表达式:
<t:Transaction xmlns:t="http://example.com/transaction">
现在我能做到:
/t:Transaction/t:collection/t:value[@t:Name='SomeName']
答案 0 :(得分:2)
您确实想要选择以下内容:
/t:Transaction/t:collection/t:value[@t:Name = 'SomeName']
...假设您在评估XPath表达式之前已声明t
作为"http://example.com/transaction"
命名空间的前缀。
对于您展示的示例XML,您可以将其压缩为//t:value[@t:Name = 'SomeName']
。
在任何情况下,您都不会忽略输入文档中的命名空间。 attributeFormDefault
在这个问题上是一个红色的鲱鱼。
如何定义选择命名空间取决于用于评估XPath表达式的API。
浏览器集成的API支持名称空间解析程序函数,该函数将表达式中使用的前缀映射到相应的名称空间URI。进一步阅读:MDN: Introduction to using XPath in JavaScript。
一个简单的解析器看起来像这样:
function nsResolver(prefix) {
var ns = {
t: "http://example.com/transaction",
};
return ns[prefix] || null;
}
请注意,XPath中的名称空间前缀不必与XML中的名称空间前缀一致。但是,他们指出的URI必须同意。
答案 1 :(得分:1)
而不是试图绕过命名空间,follow best practices并将前缀绑定到命名空间,然后使用命名空间前缀编写XPath:
p0
绑定到http://example.com/transaction
由XPath处理器提供。然后利用XPath表达式中的名称空间前缀:
/p0:Transaction/p0:collection/p0:value[@p0:Name='SomeName']