Is there a way to get element by XPath using JavaScript in Selenium WebDriver?

I am looking for something like:

getElementByXpath(//html[1]/body[1]/div[1]).innerHTML

I need to get the innerHTML of elements using JS (to use that in Selenium WebDriver/Java, since WebDriver can't find it itself), but how?

I could use ID attribute, but not all elements have ID attribute.

[FIXED]

I am using jsoup to get it done in Java. That works for my needs.


You can use document.evaluate:

Evaluates an XPath expression string and returns a result of the specified type if possible.

It is w3-standardized and whole documented: https://developer.mozilla.org/en-US/docs/Web/API/Document.evaluate

function getElementByXpath(path) {
  return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}

console.log( getElementByXpath("//html[1]/body[1]/div[1]") );
<div>foo</div>

https://gist.github.com/yckart/6351935

There's also a great introduction on mozilla developer network: https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript#document.evaluate


Alternative version, using XPathEvaluator:

function getElementByXPath(xpath) {
  return new XPathEvaluator()
    .createExpression(xpath)
    .evaluate(document, XPathResult.FIRST_ORDERED_NODE_TYPE)
    .singleNodeValue
}

console.log( getElementByXPath("//html[1]/body[1]/div[1]") );
<div>foo/bar</div>

In Chrome Dev Tools you can run the following:

$x("some xpath")

For something like $x from chrome command line api (to select multiple elements) try:

var xpath = function(xpathToExecute){
  var result = [];
  var nodesSnapshot = document.evaluate(xpathToExecute, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null );
  for ( var i=0 ; i < nodesSnapshot.snapshotLength; i++ ){
    result.push( nodesSnapshot.snapshotItem(i) );
  }
  return result;
}

This MDN overview helped: https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript