-
-
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 !