CSS 选择器或 xpath 以迭代具有特定属性的行

A CSS selector or xpath to iterate over rows with specific attributes

想象一下,我得到了这样一个 table:

<table>
  <tr><td>A</td></tr>
  <tr><td><a href="#">B</a></td></tr>
  <tr><td><a href="#">C</a></td></tr>
  <tr><td>D</td></tr>
  <tr><td><a href="#">E</a></td></tr>
  <tr><td>B</td></tr>
</table>

我想构造一个 CSS selector(首选)或 XPath(接受)来挑选出包含 a 锚点的第 n 行,这样:

selector(1) => <a href="#">B</a>
selector(2) => <a href="#">C</a>
selector(3) => <a href="#">E</a>

CSS select或

在这一点上,我很确定 CSS 不会完成这项工作,但是

'table tr:nth-child(' + n + ')'

将挑选出第 n 行,但是 selects 行无论它们是否具有 a 锚点。同样,

'table tr:nth-child(' + n + ') a'

将挑选出带有 a 锚点的行,但前提是 n 是 2、3 或 5。

XPath

对于 XPath,这匹配所有具有 a

tr
`//table//tr//a/ancestor::tr`

但我不知道如何 select 第 n 个匹配项。特别是,

`//table//tr//a/ancestor::tr[position() = 2]`

似乎select什么都没有。

如果我没理解错的话,你可以找到第 n 个 td,它有一个 <a href 像这样(你想让 C 成为第二个匹配项?):

(/table//tr/td[a[@href]])[2]

如果你不能保证一个td元素,你可以通配路径和元素:

(/table//tr//*[a[@href]])[2]

您不能使用 CSS select 或 1 执行此操作,原因有很多:

  • There is no parent selector,以及
  • There is no selector for matching the nth child satisfying an arbitrary selector.

您的 XPath 不正确,因为 a/ancestor::tr[position() = 2] returns a 元素的第二个 tr 祖先。也就是说,[position() = 2] 谓词连接到 ancestor:: 轴。此 XPath 将匹配以下 HTML:

中的中间级别 tr
<table>
  <tr><td><table>
    <tr><td><table>
      <tr><td><a href="#"></a>
    </table>
  </table>
</table>

在您的 HTML 中,每个 a 元素只有一个 tr 祖先,因此这不会 select 任何东西。

您应该使用的 XPath 是:

(//table//tr[descendant::a])[2]

这与包含 a 后代的第二个 tr 元素匹配。


1 在选择器 4 中,可能的解决方案是 table tr:nth-match(2 of :has(a)).

@BoltClock 和@StuartLC 的回答都有效。但现在我知道 XPath 中的括号可以控制运算符的优先级,一个更直接的解决方案似乎是:

(//table//tr//a)[2]

我是不是漏掉了什么?