A quick little blurb about xpath that I learned today.
Conditionals on xpath work much like wheres in SQL. If you have the following xpath:
//div[contains(@class,'class-name')][2]
that is actually saying something along the lines of:
From all divs select the ones with the class 'class-name' and have the position of 2NOT
From all divs select the 2nd one with the class 'class-name'As you can see there is a big difference in the two statements I just typed out. The reason for this is each conditional (the items inside the square brackets [ ]) are working on the nodes you are selecting from. So it's like doing a union on
//div[contains(@class,'class-name')] and //div[2]
.
So what I'm saying is //div[contains(@class,'class-name')][2]
will match something if the HTML looks something like the following:
<div>
<div></div>
<div class='class-name'></div>
</div>
But it wouldn't match if you have something like the following:
<div>
<div class='class-name'></div>
</div>
<div>
<div class='class-name'></div>
</div>
because in no instance is there a div that has the class "class-name" in the 2nd div below some other element.
In fact, it is the exact same thing as saying //div[contains(@class,'class-name') and position() = 2]
With that said, there is a solution to this. You can get subsets by using parenthese like so:
(//div[contains(@class,'class-name')])[2]
That in fact does read:
select the 2nd one from all divs with the class 'class-name'
I want to thank Stas over at Stack Overflow for asking this question Path Get first element of subset