views:

180

answers:

3

Hi

I try to index over results returned by an xpath. For example:

xpath = '//a[@id="someID"]'

can return a few results. I want to get a list of them. I thought that doing:

numOfResults = sel.get_xpath_count(xpath)
l = []
for i in range(1,numOfResults+1):
   l.append(sel.get_text('(%s)[%d]'%(xpath, i)))

would work because doing something similar with firefox's Xpath checker works:

(//a[@id='someID'])[2]

returns the 2nd result.

Ideas why the behavior would be different and how to do such a thing with selenium Thanks

A: 

In Selenium you normally do it without the extra brackets so your loop would look like the following

numOfResults = sel.get_xpath_count(xpath)
l = []
for i in range(1,numOfResults+1):
   l.append(sel.get_text('%s[%d]'%(xpath, i)))

And that will produce a valid XPath in Selenium like //a[@id='someID'][2]

AutomatedTester
That doesn't work - because it enumerates on the child a-s. Meaning that if you have two a-s matching this xpath and both have a parent div. And both are the first child of that div, then `xpath[1]` will return both links and `xpath[2]` will return none.
Guy
`//a[@id='someID'][1]` should return the first element on the page that is a link with an ID = someID and then `//a[@id='someID'][2]` will return the 2nd element. With that xpath you are using it doesnt care what the parent is. `xpath[1]` will not return an array because it is looking for the first element in an array
AutomatedTester
Guy
+2  A: 

Can you try the xpath /html/descendant::a[@id="someID"] You can replace the /html with something else that is an ancestor of your links like id('content'). You should then be able to locate individual links using [1], [2] etc.

From the XPath TR at http://www.w3.org/TR/xpath#path-abbrev:

NOTE: The location path //para[1] does not mean the same as the location path /descendant::para[1]. The latter selects the first descendant para element; the former selects all descendant para elements that are the first para children of their parents.

Dave Hunt
A: 

The answer is that you need to tell selenium that you're using xpath:

numOfResults = sel.get_xpath_count(xpath)
l = []
for i in range(1,numOfResults+1):
   l.append(sel.get_text(xpath='(%s)[%d]'%(xpath, i)))
Guy