Skip to content

Instantly share code, notes, and snippets.

@matt-curtis
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matt-curtis/0ba79643a7412b1dd64a to your computer and use it in GitHub Desktop.
Save matt-curtis/0ba79643a7412b1dd64a to your computer and use it in GitHub Desktop.
XPath + Text Nodes
var getNodeTreeXPath = function(node){
// Built from Firebug source -
// https://github.com/firebug/firebug/blob/235efff40332f85cb34b55f2da0de6bf98d083e4/extension/content/firebug/lib/xpath.js
var paths = [], nodePath, element = node;
// If text node find its place among its siblings
if(element.nodeType == Node.TEXT_NODE){
var siblings = node.parentElement.childNodes;
var nodeIndex = Array.prototype.indexOf.call(siblings, node)+1;
nodePath = "node()["+nodeIndex+"]"; element = node.parentElement;
}
if(element.id){
paths.push('*[@id="'+element.id+'"]');
} else {
// 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);
}
}
// Append text node path if we have one
if(nodePath) paths.push(nodePath);
return paths.length ? "//" + paths.join("/") : null;
};
@matt-curtis
Copy link
Author

Combined version of Firebug's XPath functions getElementTreeXPath and getElementXPath with basic text node support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment