Reputation: 35169
Imagine I am given a table like this:
<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>
I'd like to construct a CSS selector (preferred) or an XPath (accepted) that picks out the n'th row that contains an a
anchor, such that:
selector(1) => <a href="#">B</a>
selector(2) => <a href="#">C</a>
selector(3) => <a href="#">E</a>
At this point, I'm pretty sure that CSS won't do the job, but
'table tr:nth-child(' + n + ')'
will pick out the n'th row, but that selects rows whether or not they have an a
anchor. Similarly,
'table tr:nth-child(' + n + ') a'
will pick out rows with an a
anchor, but only if n
is 2, 3 or 5.
With XPath, this matches all the tr
that have an a
`//table//tr//a/ancestor::tr`
but I can't figure out how to select the n'th match. In particular,
`//table//tr//a/ancestor::tr[position() = 2]`
doesn't appear to select anything.
Upvotes: 2
Views: 1443
Reputation: 35169
Answers from @BoltClock and @StuartLC both work. But now that I know parentheses in XPath can control operator precedence, a more straightforward solution seems to be:
(//table//tr//a)[2]
Am I missing something?
Upvotes: 0
Reputation: 723548
You can't do this with a CSS selector1 for a number of reasons:
Your XPath is incorrect because a/ancestor::tr[position() = 2]
returns the second tr
ancestor of the a
element. That is, the [position() = 2]
predicate is connected to the ancestor::
axis. This XPath would match the middle-level tr
in the following HTML:
<table>
<tr><td><table>
<tr><td><table>
<tr><td><a href="#"></a>
</table>
</table>
</table>
In your HTML, each a
element has only one tr
ancestor, so this will not select anything.
The XPath you should use is:
(//table//tr[descendant::a])[2]
This matches the second tr
element that contains an a
descendant.
1 In Selectors 4, a potential solution would be table tr:nth-match(2 of :has(a))
.
Upvotes: 2
Reputation: 107247
If I understand you correctly, you can find the nth td
which has an <a href
like so (you want C
to be the 2nd match?):
(/table//tr/td[a[@href]])[2]
If you can't guarantee a td element, you can wild card the path and elements:
(/table//tr//*[a[@href]])[2]
Upvotes: 1