7

I am parsing a webpage that includes a structure like this:

<tr>
    <td>Label 1</td>
    <td>Label 2</td>
    <td>Label 3</td>
    <td>Something else</td>
<\tr>
<tr>
    <td>Item 1</td>
    <td>Item 2</td>
    <td>Item 3</td>
<\tr>

What I need to do is select an item based on it's label, so my thought is if the label is in the 3rd tag in it's row, I can grab the 3rd tag in the next row to find the item. I can't figure out a way to use the position() function in this way, and maybe xpath (1.0) is unable to handle this type of filtering.

My best attempt so far is: //td[ancestor::tr[1]/preceding-sibling::tr[1]/td[position()]]. I was hoping the position() function would grab the position of the <td> at the beginning of the xpath, since the rest of the xpath is a filter for that node.

Is what I'm trying to do even possible?

Ian Roberts
  • 120,891
  • 16
  • 170
  • 183
eldon111
  • 208
  • 2
  • 7
  • 2
    What library/programming language are you using to execute your XPaths? I don't think this can be done in pure XPath 1.0, you'd need to store the `position()` from the outer context in a variable and then use that variable inside the predicate, and how you set variables varies from tool to tool. – Ian Roberts Sep 23 '13 at 13:29
  • I'm using selenium webdriver. – eldon111 Sep 23 '13 at 13:55
  • Which selenium-webdriver language bindings are you using? It is likely easier to make use of various selenium methods rather than a pure xpath solution. – Justin Ko Sep 23 '13 at 16:12

1 Answers1

6

You're on the right track -- yes, you can use position() along with count().

To select the text Item 2 given Label 2:

//td[. = 'Label 2']/../following-sibling::tr/td[position() = count(//td[. = 'Label 2']/preceding-sibling::td)+1]/text()

Explanation: Select the nth cell where n is given by the number of sibling cells that exist before the cell that has the desired label in the previous row. In effect, use the count() function to determine position in the label row and then select the corresponding cell in the next row down by matching against its position().

kjhughes
  • 106,133
  • 27
  • 181
  • 240