I have a table like this:
<table>
<th>
<td>Area</td><td># of errors</td>
</th>
<tr><td>school</td><td>23</td></tr>
<tr><td>student</td><td>0</td></tr>
<tr><td>school</td><td>17</td></tr>
<tr><td>student</td><td>0</td></tr>
</table>
How can I select the last row for the 'Schools' Area.
Until recently I used assert_text with
//table//tr//td[contains(text(),'school')]/following::td
and a value
of 0, i.e. zero errors.
However, now I need to account for rows that have errors, but still look at the 'last' row - for an area - that has zero errors.
For this case, using
//table//tr//td[contains(text(),'school')]/following::td
incorrectly selects the first row that has the 23 errors.
I tried using tr[last()]
-
//table//tr[last()]//td[contains(text(),'school')]/following::td[2]
but the problem is that this select the last table row - which is for students. I want the last table row that is for schools (it is actually the next to last table row from all rows).
I also tried:
//table//td[contains(text(),'school')][last()]/following::td[2]
but that didn't work (it still selects the 'first' school row).
I need to be able to account for just one school row, two school rows and more than 2 school rows so I need the expression to be dynamic enough to handle that.
You are searching for an element that contains the text 'school', but the markup has the text 'School', XPath is case sensitive.
You can work around this by translating uppercase letters into lower case letters, this would make your XPath like so:
//td[contains(translate(.,'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'school')][last()]/following::td[2]
*Note*
I didn't use the XPath2 lower-case() function because it won't work in all browsers.
*Edit*
Updated for the new markup the xpath that is case insensitive would be:
//tr[td[contains(translate(.,'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'school')]][last()]/td[2]
or the more simplified version that is not case insensitive would be:
//tr[td[contains(., 'school')]][last()]/td[2]
(. is shorthand for text(), you can interchange them if you want to)
you could probably also get away with
//tr[td[.='school']][last()]/td[2]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With