2

Is there a way in Selenium RC to get the id from the xpath?

If I have the xpath

/html/body/div/div//input

I want to get the id of all the nodes associated to the xpath

2 Answers 2

7

You can use getAttribute in combination with getXpathCount.

A Selenium 1 example in Java would be:

int inputs = selenium.getXpathCount("/html/body/div/div/descendant::input").intValue();
for (int i=1; i<=inputs; i++) {
    System.out.println(selenium.getAttribute("/html/body/div/div/descendant::input[" + i + "]@id"));
}

A Selenium 2 example in Java would be:

List<WebElement> inputs = driver.findElements(By.xpath("/html/body/div/div/descendant::input"));
for (WebElement input : inputs) {
    System.out.println(input.getAttribute("id"));
}
Sign up to request clarification or add additional context in comments.

3 Comments

Your code works too but you spelled descendant wrong, so at first I was getting invalid xpath :P.
I've corrected the typo (sorry about that). I would warn however that // is not the same as /descendant:: and you may get some unexpected behaviour. Also, why use all that JavaScript when there's a Selenium command for getting an attribute?
My only argument for my code (Selenium 1) is that if you have a ton of elements, my code will only make one trip to the browser instead of one per element. In my experience, that can take a long, long time. In Selenium 2, your code seems way better, definitely.
0

You can get that by running a javascript, using this.browserbot.findElement('/html/body/div/div//input'):

Of course, this depends on the source language, but it would be something like this (in perl, untested):

#first count the number of inputs with ids
my $count = $selObj->get_xpath_count('/html/body/div/div//input[@id]');

#build a javascript that iterates through the inputs and saves their IDs
my $javascript;
$javascript .= 'var elements = [];';
$javascript .= "for (i=1;i<=$count;i++)";
$javascript .= "  elements.push(this.browserbot.findElement('/html/body/div/div/input['+i+']').id);";
#the last thing it should do is output a string, which Selenium will return to you
$javascript .= "elements.join(',');";

my $idString = $selObj->get_eval($javascript);

I always thought there should be a more direct way to do this, but I haven't found it yet!

EDITED based on the comments, the for loop count should start from 1 and include $count, also the findElement line only needs one forward-slash before input.

EDIT2 Adding a completely different idea based on further comments:

Selenium's javascripts that get attached to every page include a function called eval_xpath that returns an array of DOM elements for a given query. Sounds like what you want?

Here's what I think the javascript would look like (again, untested):

var elements = eval_xpath('/html/body/div/div//input',this.browserbot.getCurrentWindow().document);
var results = [];
for (i=0;i<elements.length;i++){
  results.push(elements[i].id);
}

results.join(',');

4 Comments

I'm sorry, I don't... the only real difference is the selenium functions called, looking at the Java docs, you need getXpathCount and getEval, both in the DefaultSelenium object
Ok i figured out how to implement this in java but I have an issue because my nodes are not input[1] to input[i]. My xpath is not an absolute xpath, basically I want all the inputs for the xpath that starts with /html/body/div/div
I think you miss understood my last comment. the path is /html/body/div/div//input but I am missing elements between the // because I don't care what is between the //. I don't have an input[1] - input[i] but I do have /html/body/div[1]/div/input[1] and /html/body/div[2]/form/div/input[1]. My xpath syntax should be correct because getxpathcount() gives me the correct number also it evaluates in Xpather.
Ahh, that's a bit more tricky.... and now that I've dug around in selenium-core, I have various untested bits for you to try :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.