I can select a row based on a specific value and then fetch the desired column. Example: Click the Action Button for the student of type Bachelor:
//td[text()='Bachelor']/following-sibling::td[@class='action']
HTML
I want to select based on negation: Click the Action Button for all students that are NOT of type Master
//td[not(text()='Master')]/following-sibling::td[@class='action']
But wrongly selects both (only Student's row should be selected):
Using chrome XPath resolver (f12) for testing for later using the XPath query in Selenium.
Couldn't find any similar example or deep explanation with the research I did.
CodePudding user response:
The reason
//td[not(text()='Master')]/following-sibling::td[@class='action']
"selects [td
elements in] Master row too," as you observe, is that
//td[not(text()='Master')]
selects all td
elements that do not have a text()
node child with a string value of 'Master'
. Significantly, that includes all of the predecessor siblings to the 'Master'
td
that you're trying to exclude, and the problem is that they too have following td
siblings with . So, you're not really excluding the row you want to exclude.
To select only the action td
elements immediately preceded by a td
whose string value is not 'Master'
, use this XPath:
//td[@class='action'][preceding-sibling::*[1][self::td][not(.='Master')]]
Or, you can simply test the row rather than the immediate sibling:
//tr[not(td='Master')]/td[@class='action']
Note that the former XPath will be sensitive to td
positioning while the latter XPath will not.
See also
CodePudding user response:
Just use:
//td[5][not(. = 'Master])]/following-sibling::td[@class = 'action']
or simply:
//tr[not(td[5] = 'Master')]/td[@class = 'action']
I think it is dangerous to use just //tr[not(td = 'Master')]
because there could easily be someone with family name 'Master'