Selenium Xpath to find a table cells inside a div tag
Wrong:
*//div[@id='AutoText']//td[contains[Text(), 'celltext']]
*//div[@id='AutoText']//table//tbody//tr[td//Text()[contains[., 'celltext']]
Correct (with shorter alternatives):
//div[@id='AutoText']//td[contains(text(), 'celltext')]
//div[@id='AutoText']//td[contains(., 'celltext')]
//div[@id='AutoText']/table/tbody/tr[td//text()[contains(., 'celltext')]
//div[@id='AutoText']/table/tbody/tr[td[contains(., 'celltext')]]
-
contains()
is a function -
text()
needs to be lowercase - predicates can be nested
- don't use
//
when you don't have to
Note
.
refers to "this node" and, when given as an argument to a string function such as contains()
, is the equivalent of string(.)
. This, however, is not at all the same as text()
.
string(.)
creates the concatenation of all text nodes inside the current node, no matter how deeply nested. text()
is a node test and by default selects only the direct children.
In other words, if the current node was <td>foo <b>bar</b> baz</td>
, contains(text(), 'bar')
would actually be false. (So would contains(text(), 'baz')
, for a different reason.)
contains(., 'bar')
on the other hand would return true, so would contains(., 'baz')
.
Only when the current node contains nothing but a single text node, text()
and .
are equivalent. Most of the time, you will want to work with .
instead of text()
. Set up your predicates accordingly.
Calle
Updated on June 05, 2022Comments
-
Calle almost 2 years
I have the following HTML code that I need to check if text exists within a table cell:
<div class="background-ljus" id="AutoText"> <table class="topAlignedCellContent"> <tbody> <tr> <td>X1</td> </tr> <tr> <td>X2</td> </tr> </tbody> </table> <table> <tbody> <tr> <td>Y1</td> <td>Y2</td> </tr> </tbody> </table> <table> <tbody> <tr> <td>Z1</td> <td>Z2</td> </tr> </tbody> </table> </div>
I have solved it like this:
By locator = getLocator(CommonConst.XPATH, "*//div[@" + type + "='" + anyName + "']"); fluentWait(locator); WebElement div = getDriver().findElement(locator); List<WebElement> cells = div.findElements(By.tagName("td")); for (WebElement cell : cells) { if (cell.getText().contains(cellText)) { foundit = true; } }
But i think its a bit slow because I need to do this several times. I tried to do this with only XPath but had no luck.
"*//div[@id='AutoText']//td[contains[Text(), 'celltext']]" "*//div[@id='AutoText']//table//tbody//tr[td//Text()[contains[., 'celltext']]"
Anyone have a suggestion about why my XPath isn't working?