I was looking for two clean,
tiny and elegant element-to-xpath functions
producing short and complete xpaths like
id("main")/ul/li[3] or
/html/body/ul/li[3] for a given element,
and figured I'd just craft my own.
| // get a short, clean XPath path to a given element el, within the current page | |
| getXPathTo = (el) => { | |
| if (!el) return ''; | |
| var p = el.parentNode; | |
| if (!p) return ''; | |
| var t = el.tagName; | |
| var c = Array.from(p.children).filter(n => n.tagName === t); | |
| var n = c.length === 1 ? '' : '[' + (1 + c.indexOf(el)) + ']'; | |
| var path = getXPathTo(p) + '/' + t.toLowerCase() + n; | |
| // see if we can do better (= shorter than, or equal to) with an id selector: | |
| var id = el.id; | |
| if (id && // id exists | |
| id.length + 6 <= path.length && // id was shorter | |
| document.querySelectorAll('#' + id).length === 1) // id was unique in page | |
| return 'id("'+ id +'")'; | |
| return path; | |
| }; | |
| // get a root-relative XPath to an element | |
| getRootXPathTo = (el) => { | |
| if (!el) return ''; | |
| var p = el.parentNode; | |
| if (!p) return ''; | |
| var t = el.tagName; | |
| var c = Array.from(p.children).filter(n => n.tagName === t); | |
| var n = c.length === 1 ? '' : '[' + (1 + c.indexOf(el)) + ']'; | |
| return getRootXPathTo(p) + '/' + t.toLowerCase() + n; | |
| }; |
| // get a short, clean XPath path to a given element el, within the current page | |
| function getXPathTo(el) { | |
| if (!el) return ''; | |
| var p = el.parentNode; | |
| if (!p) return ''; | |
| var t = el.tagName; | |
| var c = [].slice.call(p.children).filter(function(n) { | |
| return n.tagName === t; | |
| }); | |
| var n = c.length === 1 ? '' : '[' + (1 + c.indexOf(el)) + ']'; | |
| var path = getXPathTo(p) + '/' + t.toLowerCase() + n; | |
| // see if we can do better (= shorter than, or equal to) with an id selector: | |
| var id = el.id; | |
| if (id && // id exists | |
| id.length + 6 <= path.length && // id was shorter | |
| document.querySelectorAll('#' + id).length === 1) // id was unique in page | |
| return 'id("'+ id +'")'; | |
| return path; | |
| } | |
| // get a root-relative XPath to an element | |
| function getRootXPathTo(el) { | |
| if (!el) return ''; | |
| var p = el.parentNode; | |
| if (!p) return ''; | |
| var t = el.tagName; | |
| var c = [].slice.call(p.children).filter(function(n) { | |
| return n.tagName === t; | |
| }); | |
| var n = c.length === 1 ? '' : '[' + (1 + c.indexOf(el)) + ']'; | |
| return getRootXPathTo(p) + '/' + t.toLowerCase() + n; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment