【问题标题】:Difference between "//" and "/" in XPath?XPath 中“//”和“/”的区别?
【发布时间】:2017-03-29 17:17:35
【问题描述】:

我正在尝试使用 XPath for python-selenium。

我使用this link 尝试了一些教程中的 XPath:

所以我尝试了这两种 XPath 变体。

  1. 这个表达式

    //webengagedata//preceding-sibling::*
    

返回 14 个结果

  1. 还有这个表达

    //webengagedata/preceding-sibling::*
    

返回 9 个结果

“//”如何匹配另外 5 个结果?

【问题讨论】:

  • 这是一个很好的问题,除了站外链接。 (问题应努力提出即使场外资源发生变化也将保持有用的 minimal reproducible example。)参见my answer below that 涵盖了不依赖任何场外资源的概念。谢谢。

标签: xml selenium xpath


【解决方案1】:

/// 一般

child (/) 和 descendant-or-self (//) 都是 axes in XPath

  • //child::node()/ 的缩写。

    使用/ 选择节点的直接子节点

  • ///descendant-or-self::node()/ 的缩写。

    使用// 选择 一个节点、它的子节点、它的孙节点等等 递归。


///preceding-sibling::*

您的具体问题询问//preceding-sibling::*/preceding-sibling::* 之间的区别。

由于您的数据是异地且复杂的,因此让我们考虑这个现有且更简单​​的 XML:

<r>
  <a/>
  <b>
    <c/>
    <d/>
  </b>
</r>

对于这个 XML,

  1. /r/preceding-sibling::* 什么都不选择,因为 r 没有 之前的兄弟姐妹。
  2. /r//preceding-sibling::* 选择前面的兄弟元素 r 的所有后代或自身节点。即abcd。 (请记住,/r//preceding-sibling::*/descendant-or-self::node()/preceding-sibling::* 的缩写,不是 /descendant-or-self::*/preceding-sibling::*)请注意,即使 bd 是前任兄弟姐妹,也没有 元素,它们是文本节点的前代兄弟,因为上面的XML在bd之后有空格。如果删除了所有空格,则只会选择 ac
  3. /r/descendant::*/preceding-sibling::* 选择 r 的所有后代 elements 的前面的兄弟元素。即ac。请注意,bd 未被选中,因为它们不是 r 的任何后代 元素 的同级元素之前 - 与前面的示例不同,text 节点不符合条件。

【讨论】:

  • 我能够掌握 1 和 2。我仍然对后代的一件小事感到困惑。不是descendant::*用来获取上下文节点的所有子节点或子节点吗?如果是,不应该 /r/descendant::*/preceding-sibling::* 返回所有子节点 a 和 b 以及子子节点 c 和 d 吗?
  • @Prasanth,我已更新问题以正确解决您非常有见地的后续问题,这让我意识到我的解释有误。谢谢。
  • 哦,这太棒了。我假设/descendant::* 的输出将给出a 'b' c d,其中b 将不包括其子cd作为输出的一部分。但是b 元素作为一个整体将与其子元素cd &lt;b&gt; \n &lt;c/&gt; and hence the preceding-element` --> c 一起呈现。非常感谢您您的耐心,让我在回答我的菜鸟问题时感到很自在。这是我在stackoverflow中的第一个问题,现在我意识到我迟到了这个美丽的世界。干杯。
【解决方案2】:

你的例子

//webengagedata/preceding-sibling::* ---> returned 9 results

因为只有 9 个标签是 webengagedatatags 的确切兄弟,所以它显示 9 条记录

//webengagedata//preceding-sibling::* ---> returned 14 results

这里正在考虑子标签以及biziclop所说的x/descendant-or-self::node()/y

【讨论】:

    【解决方案3】:

    区别在于x//yx/descendant-or-self::node()/y的简写。

    就是这样。

    因此,第一个查询选择 &lt;webengagedata&gt; 之后有另一个标签的所有后代,而第二个查询只选择标签本身的前面的兄弟姐妹。

    缩写xpath语法规则解释here

    【讨论】:

    • 请告诉我这是否正确.. //webengage//preceding-sibling::* = //webengage//child::* + //webengage/preceding-sibling::*
    【解决方案4】:

    xpath中'/'和'//'的区别在于,'/'用于识别该区域中的元素,'//'用于条件后的整个页面

    【讨论】:

    • 这个答案使用了如此不精确的语言,以至于它没用;它应该被删除。
    猜你喜欢
    • 2021-01-08
    • 2021-04-26
    • 2016-06-07
    • 2020-02-25
    • 2021-04-23
    • 1970-01-01
    相关资源
    最近更新 更多