13

All the examples of findElement(By.xpath) I've seen search the whole page, e.g.

WebElement td = driver.findElement(By.xpath("//td[3]"));

What I want to achieve is this:

WebElement tr = ... // find a particular table row (no problem here)
WebElement td = tr.findElement(By.xpath("/td[3]"));  // Doesn't work!

I've also tried other variations without luck: "td[3]", "child::td[3]"

Using "//td[3]" finds the first matching node in the whole page, i.e. not restricted to my tr. So it's looking like when you findElement by xpath, the WebElement on which you call findElement() counts for nothing.

Is it possible to scope findElement(By.xpath) to a particular WebElement?

(I'm using Chrome, in case it matters.)

PLEASE NOTE: By.xpath("//td[3]") is just an example. I'm not looking for alternative ways of achieving the same thing. The question is just about trying to ascertain whether foo.findElement() takes any notice of foo when used with a By.xpath selector.

David Easley
  • 1,347
  • 1
  • 16
  • 24

5 Answers5

11

Based on ZzZ's answer I think the issue is that the queries you are trying are absolute instead of relative. By using a starting / you force absolute search. Instead use the tag name as ZzZ suggested, ./ or .//.

Look in the XPath docs under "Location Path Expression"

Adam
  • 3,675
  • 8
  • 45
  • 77
  • 1
    This is true, and also explained in [Selenium docs](http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/WebElement.html) for WebElement Interface, under "findElements" method. – gamliela Oct 20 '12 at 18:52
5

I also ran into this issue and spent quite a lot of time trying to figure out the workaround. And this is what I figured out:

WebElement td = tr.findElement(By.xpath("td[3]"));

Not sure why, but this works for me.

ZzZ
  • 51
  • 4
  • 2
    By not having a leading slash (or two) the query is relative instead of absolute. See my answer for a link to the docs. – Adam Nov 21 '11 at 22:02
  • WebDriver hung/waited for me until I changed the implicit wait time back to 0 (the default). http://seleniumhq.org/docs/04_webdriver_advanced.html#implicit-waits – Jayen Nov 22 '12 at 03:03
2

I think this might be a bug in the way that Selenium2 uses xpath. However, I believe I've successfully limited the scope using "::ancestor" before.

In any event, have you tried using Css Selectors to solve this? Is that an option for you? Try this:

tr.findElement(By.cssSelectors("td:nth-of-type(3)"));

This should do the job and is the equivalent of what you tried initially:

tr.findElement(By.xpath("//td[3]"));

SlimDavid
  • 81
  • 1
  • 5
  • Thanks for the 'ancestor::' tip - I will try this. As I commented in the last answer, the "/td[3]" was just an example. I do prefer non-xpath selectors where possible (not least because they're so unreliable in IE). But this question was purely to try and ascertain whether you can do a scoped query using xpath. – David Easley Sep 09 '11 at 10:20
0

WebElement td = tr.findElement(By.xpath("/td[3]"));

If you only want to to find the child elements of the tr use a relative path not an absolute.

This should work:

int index = 3;
List<WebElement> tds = tr.findElements(By.xpath(".//td"));
System.out.println(tds[index].getText());
hennr
  • 2,632
  • 2
  • 23
  • 26
0
what i m understanding that u want to retrieve a particular td from a tr, so here's a snippet you can try it with your code to find 3rd td...



WebElement tr=//...find a particular table row 
    List<WebElement> columns = tr.findElements(By.tagName("td"));
    Iterator<WebElement> j = columns.iterator();
    int count=0;
    while(j.hasNext())  
            {   
                WebElement column = j.next();
                if(count==2)
                {
                    System.out.print(column.getText());
                }
                count++;
            }

You can change count value in if condition to retrieve another td..
Hope this will help you..
  • Thanks for going to all this trouble, Jay, but the "/td[3]" was just an example. I want to know whether you can do this kind of scoped query using xpath, because being able to do so would be highly convenient in certain situations. – David Easley Aug 27 '11 at 11:27