在 XPath 谓词中执行双斜杠的工作方式与路径本身的工作方式相同 [英] Do double slash in XPath predicate work the same as in the path itself

查看:30
本文介绍了在 XPath 谓词中执行双斜杠的工作方式与路径本身的工作方式相同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 XPather 处理了不同的 XPath 查询(仅适用于较旧的 firefox 版本)并注意到以下查询的结果之间存在差异

这个显示了一些结果

//div[descendant::table/descendant::td[4]]

这个列出空列表

//div[//table//td[4]]

它们是由于某些规则而不同还是只是 XPath 解释器的特定实现的不当行为?(好像是从FF引擎中使用的,XPather只是一个优秀的简单查询GUI)

解决方案

With XPath 1.0 ///descendant-or-self::node()/的缩写code> 所以你的第一个路径是 /descendant-or-self::node()/div[descendant::table/descendant::td[4]] 而第二个与 /descendant-or-self::node()/div[/descendant-or-self::node()/table/descendant-or-self::node()/td[4]].所以主要的区别在于,在第一个谓词中,您会查找相对于 div 元素的后代,而在第二个谓词中,您会查找根节点 / 的后代(也称为文档节点).您可能希望 //div[.//table//td[4]] 使第二个路径表达式更接近第一个.

这是一个示例:

<身体><div><表格><tr><td>1</td></tr><tr><td>2</td></tr><tr><td>3</td></tr><tr><td>4</td></tr></tbody>

</html>

使用该示例,路径 //div[descendant::table/descendant::td[4]] 选择 div 元素,因为它有一个 table 子节点,它有第四个 td 后代.

但是使用 //div[.//table//td[4]] 我们寻找 //div[./descendant-or-self::node()/table/descendant-or-self::node()/td[4]]//div[./descendant-or-self::node()/table/descendant- 的缩写或-self::node()/child::td[4]] 并且没有元素具有第四个 td 子元素.

我希望这能解释差异,如果您使用 //div[.//table/descendant::td[4]] 那么您应该得到与原始表单相同的结果.

I played with different XPath queries with XPather (works only with older firefox versions) and notice a difference between the results from the following queries

This one shows some results

//div[descendant::table/descendant::td[4]] 

This one lists empty list

//div[//table//td[4]]

Are they different due to some rules or it's just misbehavior of particular implementation of XPath interpreter? (Seems like used from FF engine, XPather is just an excellent simple GUI for querying)

解决方案

With XPath 1.0 // is an abbreviation for /descendant-or-self::node()/ so your first path is /descendant-or-self::node()/div[descendant::table/descendant::td[4]] while the second is rather different with /descendant-or-self::node()/div[/descendant-or-self::node()/table/descendant-or-self::node()/td[4]]. So the major difference is that inside your first predicate you look down for descendants relative to the div element while in the second predicate you look down for descendants from the root node / (also called the document node). You might want //div[.//table//td[4]] for the second path expression to come closer to the first one.

[edit] Here is a sample:

<html>
  <body>
    <div>
      <table>
        <tbody>
          <tr>
            <td>1</td>
          </tr>
          <tr>
            <td>2</td>
          </tr>
          <tr>
            <td>3</td>
          </tr>
          <tr>
            <td>4</td>
          </tr>
        </tbody>
      </table>
    </div>
  </body>
</html>

With that sample the path //div[descendant::table/descendant::td[4]] selects the div element as it has a table child which has a fourth td descendant.

However with //div[.//table//td[4]] we look for //div[./descendant-or-self::node()/table/descendant-or-self::node()/td[4]] which is short for //div[./descendant-or-self::node()/table/descendant-or-self::node()/child::td[4]] and there is no element having a fourth td child element.

I hope that explains the difference, if you use //div[.//table/descendant::td[4]] then you should get the same result as with your original form.

这篇关于在 XPath 谓词中执行双斜杠的工作方式与路径本身的工作方式相同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆