【问题标题】:How to select ranged ancestor/descendent using xpath?如何使用 xpath 选择远程祖先/后代?
【发布时间】:2021-12-21 14:26:18
【问题描述】:

如果我想选择一个 div 的所有直接 <p>...</p> 标记后代,我会写

div/p

如果我想选择一个 div 的所有次要 <p>...</p> 标记后代,我会写

div/*/p

是否可以指定一个范围?

div/descendent[1-2]::p // find all immediate and secondary descendent tags

【问题讨论】:

  • 这个 xpath 选择 p 和 1 或 2 个 div 祖先,但它不是数字 //p[./parent::div[not(parent::div)] or ./parent::div[parent::div[not(parent::div)]]]
  • 您已将它标记为 Selenium,这是您可能正在寻找 XPath 1.0 解决方案的唯一线索。但是,如果您可以考虑 XPath 2.0+,那么您可以选择 div/(*|.)/(*|.)/p

标签: html selenium xpath


【解决方案1】:

可能最简单的表达方式是使用联合运算符。

div/p | div/*/p(div | div/*)/p

据我所知,没有一种特别简洁的方式来表达选择具有一系列祖先的后代的想法,但根据输入,类似的事情是可能的。

给定

<root>
   <div>
      <p>good</p>
   </div>
   <div>
      <foo>
         <p>also good</p>
      </foo>
   </div>
   <div>
      <foo>
         <bar>
            <p>this one is not good</p>
         </bar>
      </foo>
   </div>
</root>

...您可以使用//p[count(./ancestor::*) &lt; 4] 仅选择想要的节点。

在这种情况下,这似乎不是比使用联合运算符更好的解决方案。

对于目标和父级“之间”的真实节点范围,我能想到的最接近的节点是这样的:

//p[count(ancestor::*) - count(ancestor::div[1]/*) &lt; 3]

【讨论】:

  • 感谢您的回复。但请记住,[1-2] 范围是退化的情况。更大的范围是我真正感兴趣的范围。
  • 我认为有一种解决方案可以表达“选择具有一定数量的祖先的节点,这些节点也是特定祖先的后代”的想法,我可以对其进行测试。我假设仅写 div//p 不足以满足您的预期用例?
  • 你猜对了。我本质上只是试图将其用作使我的 xpath 对简单的层次结构更改更加健壮的方法。因此,我不会检查直接元素后代,而是给它一个范围(一些回旋余地)。兄弟姐妹/祖先/等也可以这样说。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-05
  • 2011-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-13
相关资源
最近更新 更多