7

I'm using selenium to get some text on my webpage using xpath.

The page tag structure is as follows -

<span id="data" class="firefinder-match">
    Seat Height, Laden
  <sup>
     <a class="speckeyfootnote" rel="p7" href="#">7</a>
  </sup>
</span>

If I use the following code -

driver.findElement(By.xpath("//span[@id='data']")).getText();

I get the result = Seat Height, Laden 7

But I want to avoid reading the text within the <sup> tags and get the result Seat Height, Laden

Please let me know which xpath expression I can use to get my desired result.

Petr Janeček
  • 37,768
  • 12
  • 121
  • 145
Hari Reddy
  • 3,808
  • 4
  • 33
  • 42
  • 3
    Um. In plain XPath (that would be able to return Strings and not only WebElements), you could do `//span[@id='data']/text()[1]`. One possible solution I can think of uses JS, the second gets the whole text and then deletes everything from child elements. Both solutions are rather ugly and I would like to see a nicer one. Anyway, if there's no answer in some reasonable short time, I'll post it. – Petr Janeček May 30 '12 at 08:44
  • 1
    Any reason why xpath is your only option? Webdriver takes longest to locate an element by the xpath – Amey May 30 '12 at 14:57
  • well I use xpath only because I'm comfortable with it. If there is any other way to solve my problem, I will be grateful. – Hari Reddy May 31 '12 at 04:24
  • 1. As the span has id, it is the best to use id instead of xpath. 2. cssSelector is faster than xpath, that's why I suggest to use cssSelector instead of xpath. – Ripon Al Wasim Sep 06 '12 at 07:11
  • According to the post below, you can't select text nodes by css either: http://stackoverflow.com/questions/5688712/is-there-a-css-selector-for-text-nodes-elements. So selecting by css won't help – user152468 Apr 23 '14 at 14:07

1 Answers1

8

I don't know about any way to do this in Selenium, so there's my JS solution. The idea is to get all children of the element (including the text nodes) and then select only the text nodes. You might need to add some .trim() (or JS equivalent) calls to get rid of unneeded spaces.

The whole code:

WebElement elem = driver.findElement(By.id("data"));
String text;
if (driver instanceof JavascriptExecutor) {
    text = ((JavascriptExecutor)driver).executeScript(
            "var nodes = arguments[0].childNodes;" +
            "var text = '';" +
            "for (var i = 0; i < nodes.length; i++) {" +
            "    if (nodes[i].nodeType == Node.TEXT_NODE) {" +
            "        text += nodes[i].textContent;" +
            "    }" +
            "}" +
            "return text;"
            , elem);
}

And just the JS for better readability.

var nodes = arguments[0].childNodes;
var text = '';
for (var i = 0; i < nodes.length; i++) {
    if (nodes[i].nodeType == Node.TEXT_NODE) {
        text += nodes[i].textContent;
    }
}
return text;
Petr Janeček
  • 37,768
  • 12
  • 121
  • 145
  • Hey nice solution to get the result through the JS. But I want to ask if there is anything like a ! operator in xpath by which we can neglect certain tags. – Hari Reddy Jun 01 '12 at 04:03
  • 1
    Yes, there is. However, it won't work in this particular case since you are still selecting the outer element and that contains all the child elements by default. The text node is also a child element of it and a usual parser could get it. WebDriver is not a usual parser and does not have this functionality. Yet. If you want to know any particular XPath, feel free to ask. – Petr Janeček Jun 01 '12 at 11:24