首页 文章

限定属性的xpath

提问于
浏览
1

我正在使用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 回答

  • 1

    您实际上想要选择以下内容:

    /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必须同意 .

  • 2

    而不是试图绕过命名空间,并将前缀绑定到命名空间,然后使用命名空间前缀编写XPath:

    • 使用XPath处理器提供的机制将 p0 绑定到 http://example.com/transaction .

    • 然后利用XPath表达式中的名称空间前缀:

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

相关问题