【问题标题】:Is this simple XPath query correct?这个简单的 XPath 查询是否正确?
【发布时间】:2011-02-04 21:28:04
【问题描述】:

我的文档格式如下:

<Root>
    <A />
    <C />
    <B />
    <A>
        <B>
            <A />
            <C /> 
        </B>
    </A>
</Root>

我想“捕获”所有元素 AB 并将它们列在新文档中:

<A /> <B /> <A /> <B /> ...

使用 XPath,查询会是(以 Root 作为上下文节点):

.//*[A | B]

【问题讨论】:

  • 没有。查询出现在一个巨大的Java程序中间,不容易调试。
  • 不要调试巨型程序。编写一个很小的程序,将数据加载到 DOM 中并向其发射 xpath,并测量飞出的基本粒子。
  • 好问题,+1。请参阅我的答案以获取不使用任何函数且仅遍历 XML 文档一次的简短 XPath 表达式。 :)

标签: xml xpath


【解决方案1】:

使用

//*[self::A or self::B]

这会选择文档中所有AB 的元素。

只遍历文档一次 :)

【讨论】:

  • 这个比答案1和2好
  • 为什么这个答案比.//*[name()="A" or name()="B"]好?这个答案不是也只遍历文档一次吗?使用name() 函数有那么糟糕吗?我真的不知道。我是 XPath 菜鸟。 :)
  • 最有问题的部分是开头的.——这使得答案通常是错误的。在这种情况下,不需要使用name() 函数——使用self:: 轴更具可读性和效率。
  • 为什么使用点 (.) 不好?是否会引入不必要的开销?
  • ./SomeExpression 表示必须在当前节点上应用SomeExpression。因此,Xpath 引擎花费一些精力来确定哪个是当前节点。我很惊讶效率有如此大的差异。我建议不要使用.,因为您的 XPath 表达式将根据表达式评估开始时的当前节点来选择不同的节点集。
【解决方案2】:

根据 Welbog 的回答,我想出了这个:

.//*[name()="A" or name()="B"]

它做了应该做的事情。

【讨论】:

    【解决方案3】:

    您可以简单地写//A|//B(前一个似乎不起作用,除非在一个在线 xpath 测试仪中,这将教会我信任他们)。虽然这会遍历树两次。

    你原来的表达是:给我所有的元素(//*),它有一个名为A或B([A|B])的子元素,因为当评估谓词部分([]位)时,上下文节点是已经是您正在检查的节点,因此谓词中的任何内容都与该上下文相关。

    【讨论】:

    • 有趣。没有意识到这个事实。这就是为什么你应该总是测试.. 谢谢。 +1
    猜你喜欢
    • 2011-08-21
    • 1970-01-01
    • 1970-01-01
    • 2013-07-06
    • 2018-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多