Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to calculate the XPath position of an element using Javascript?

Let's say I have a large HTML file with different kinds of tags, similar to the StackOverflow one you're looking at right now.

Now let's say you click an element on the page, what would the Javascript function look like that calculates the most basic XPath that refers to that specific element?

I know there are an infinite ways of refering to that element in XPath, but I'm looking for something that just looks at the DOM tree, with no regard for IDs, classes, etc.

Example:

<html> <head><title>Fruit</title></head> <body> <ol>   <li>Bananas</li>   <li>Apples</li>   <li>Strawberries</li> </ol> </body> </html> 

Let's say you click on Apples. The Javascript function would return the following:

/html/body/ol/li[2] 

It would basically just work its way upward the DOM tree all the way to the HTML element.

Just to clarify, the 'on-click' event-handler isn't the problem. I can make that work. I'm just not sure how to calculate the element's position within the DOM tree and represent it as an XPath.

PS Any answer with or without the use of the JQuery library is appreciated.

PPS I completely new to XPath, so I might even have made a mistake in the above example, but you'll get the idea.

Edit at August 11, 2010: Looks like somebody else asked a similar question: generate/get the Xpath for a selected textnode

like image 847
Marc Avatar asked Aug 11 '10 00:08

Marc


People also ask

Can we get element by XPath in JavaScript?

To identify a WebElement using xpath and javascript you have to use the evaluate() method which evaluates an xpath expression and returns a result.

How do you find the current position of an element?

Use the Element. getBoundingClientRect() Function to Get the Position of an Element in JavaScript. The getBoundingClientRect() function produces a DOMRect object containing information about an element's size and position in the viewport.

How do you get the position element XY?

The position of (X, Y) means the co-ordinate of an element at the top-left point in a document. X represent the horizontal position and Y represent the vertical position. Use element. getBoundingClientRect() property to get the position of an element.

How do I find XPath in HTML?

You can press F12 to get the check page, and select your hoped html code, hit the mouse 2, it has the copy option, there is a copy Xpath.


1 Answers

Firebug can do this, and it's open source (BSD) so you can reuse their implementation, which does not require any libraries.

3rd party edit

This is an extract from the linked source above. Just in case the link above will change. Please check the source to benefit from changes and updates or the full featureset provided.

Xpath.getElementXPath = function(element) {     if (element && element.id)         return '//*[@id="' + element.id + '"]';     else         return Xpath.getElementTreeXPath(element); }; 

Above code calls this function. Attention i added some line-wrapping to avoid horizontal scroll bar

Xpath.getElementTreeXPath = function(element) {     var paths = [];  // Use nodeName (instead of localName)      // so namespace prefix is included (if any).     for (; element && element.nodeType == Node.ELEMENT_NODE;             element = element.parentNode)     {         var index = 0;         var hasFollowingSiblings = false;         for (var sibling = element.previousSibling; sibling;                sibling = sibling.previousSibling)         {             // Ignore document type declaration.             if (sibling.nodeType == Node.DOCUMENT_TYPE_NODE)                 continue;              if (sibling.nodeName == element.nodeName)                 ++index;         }          for (var sibling = element.nextSibling;              sibling && !hasFollowingSiblings;             sibling = sibling.nextSibling)         {             if (sibling.nodeName == element.nodeName)                 hasFollowingSiblings = true;         }          var tagName = (element.prefix ? element.prefix + ":" : "")                            + element.localName;         var pathIndex = (index || hasFollowingSiblings ? "["                     + (index + 1) + "]" : "");         paths.splice(0, 0, tagName + pathIndex);     }      return paths.length ? "/" + paths.join("/") : null; }; 
like image 89
Matthew Flaschen Avatar answered Sep 23 '22 00:09

Matthew Flaschen