想象一下,我得到了一张这样的表:
<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选择器(首选)或XPath(已接受),它选出包含a
锚点的第n行,这样:
selector(1) => <a href="#">B</a>
selector(2) => <a href="#">C</a>
selector(3) => <a href="#">E</a>
此时,我很确定CSS不会胜任这项工作,但是
'table tr:nth-child(' + n + ')'
将挑选出第n行,但是无论他们是否拥有a
锚,都会选择行。同样,
'table tr:nth-child(' + n + ') a'
会选择带有a
锚点的行,但前提是n
为2,3或5。
使用XPath,这会匹配具有tr
a
`//table//tr//a/ancestor::tr`
但我无法弄清楚如何选择第n场比赛。特别是,
`//table//tr//a/ancestor::tr[position() = 2]`
似乎没有选择任何内容。
答案 0 :(得分:2)
由于多种原因,您无法使用CSS选择器 1 执行此操作:
您的XPath不正确,因为a/ancestor::tr[position() = 2]
会返回tr
元素的第二个a
祖先。也就是说,[position() = 2]
谓词连接到ancestor::
轴。此XPath将匹配以下HTML中的中间级tr
:
<table>
<tr><td><table>
<tr><td><table>
<tr><td><a href="#"></a>
</table>
</table>
</table>
在您的HTML中,每个a
元素只有一个tr
祖先,因此不会选择任何内容。
您应该使用的XPath是:
(//table//tr[descendant::a])[2]
这匹配包含tr
后代的第二个a
元素。
1 在选择器4中,潜在的解决方案是table tr:nth-match(2 of :has(a))
。
答案 1 :(得分:1)
如果我理解正确,你可以找到td
这样的<a href
(你希望C
成为第二场比赛吗?):
(/table//tr/td[a[@href]])[2]
如果你不能保证一个td元素,你可以通过外卡路径和元素:
(/table//tr//*[a[@href]])[2]
答案 2 :(得分:0)
来自@BoltClock和@StuartLC的答案都有效。但是现在我知道XPath中的括号可以控制运算符优先级,一个更简单的解决方案似乎是:
(//table//tr//a)[2]
我错过了什么吗?