【问题标题】:xpath for qualified attributes限定属性的 xpath
【发布时间】:2016-01-11 12:44:54
【问题描述】:

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

我还可以使用以下方法获取 &lt;value&gt; 节点的整个集合:

//*[local-name()='value']

考虑到命名空间限制,是否有更简洁、更精确的方法来获取我想要的节点?第三方 javascript 库不是一个选项。


编辑

感谢您的快速回复。我会在这里注意,通过添加默认命名空间前缀,解决了 xpath 查询表达式:

<t:Transaction xmlns:t="http://example.com/transaction">

现在我可以做:

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

【问题讨论】:

    标签: xml xpath


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案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 必须一致。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-12
        • 1970-01-01
        • 2016-01-04
        • 1970-01-01
        • 2022-01-15
        • 2019-02-03
        相关资源
        最近更新 更多