限定属性的xpath

时间:2015-10-13 16:46:19

标签: xml xpath

我正在使用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']

2 个答案:

答案 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:

  1. 使用该机制将p0绑定到http://example.com/transaction 由XPath处理器提供。
  2. 然后利用XPath表达式中的名称空间前缀:

    /p0:Transaction/p0:collection/p0:value[@p0:Name='SomeName']