-
-
Save iimos/e9e96f036a3c174d0bf4 to your computer and use it in GitHub Desktop.
function xpath(el) { | |
if (typeof el == "string") return document.evaluate(el, document, null, 0, null) | |
if (!el || el.nodeType != 1) return '' | |
if (el.id) return "//*[@id='" + el.id + "']" | |
var sames = [].filter.call(el.parentNode.children, function (x) { return x.tagName == el.tagName }) | |
return xpath(el.parentNode) + '/' + el.tagName.toLowerCase() + (sames.length > 1 ? '['+([].indexOf.call(sames, el)+1)+']' : '') | |
} | |
// Usage: | |
// Getting xpath for node: | |
var xp = xpath(elementNode) | |
// Executing xpath: | |
var iterator = xpath("//h2") | |
var el = iterator.iterateNext(); | |
while (el) { | |
// work with element... | |
el = iterator.iterateNext(); | |
} |
Need help to implement your function, after injecting the js on the browser this is my result,
XpathResult { resultType:4, invalidIteratorState: false}
@ogarciacapetillo I have added the usage examples. Sorry for the delayed response, i have not recieved any notifications.
The code doesn't work in IE 11.
When el
is HTMLHtmlElement
, el.parentNode.children
is undefined
, thus line 5 throws exception.
My suggestion is to change the bottom part to
if (el.parentNode.nodeType === 1)
{
var sames = [].filter.call(el.parentNode.children, function(x) { return x.tagName === el.tagName });
return getSelector(el.parentNode) + '/' + el.tagName.toLowerCase() + (sames.length > 1 ? '[' + (sames.indexOf(el) + 1) + ']' : '');
} else
return el.tagName.toLowerCase();
Why is the iterator needed? Shouldn't the function always lead to a single element?
BTW, thanks for this amazing piece of cake! It is working good so far.
Works great! Thank you so much
ps: as xpath isn't truly unique, got any thoughts on making it unique?
I'm thinking something like... combining xpath + href + css selectors to make a unique generated ID etc.
nice !