XPath Conditionals On Subsets

Submitted by allan on Tue, 10/23/2012 - 16:59
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 2 NOT 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