XPath Helper
From Greasespot Wiki
Jump to navigationJump to search
Run a particular XPath expression p against the context node context (or the document, if not provided) with this overloaded XPath helper.
Returns the results as an array, unless a value of false is passed in.
function $x() {
let x='';
let node=document;
let type=0;
let fix=true;
let i=0;
let cur;
function toArray(xp) {
let final=[], next;
while (next=xp.iterateNext()) {
final.push(next);
}
return final;
}
while (cur=arguments[i++]) {
switch (typeof cur) {
case "string": x+=(x=='') ? cur : " | " + cur; continue;
case "number": type=cur; continue;
case "object": node=cur; continue;
case "boolean": fix=cur; continue;
}
}
if (fix) {
if (type==6) type=4;
if (type==7) type=5;
}
// selection mistake helper
if (!/^\//.test(x)) x="//"+x;
// context mistake helper
if (node!=document && !/^\./.test(x)) x="."+x;
let result=document.evaluate(x, node, null, type, null);
if (fix) {
// automatically return special type
switch (type) {
case 1: return result.numberValue;
case 2: return result.stringValue;
case 3: return result.booleanValue;
case 8:
case 9: return result.singleNodeValue;
}
}
return fix ? toArray(result) : result;
}
Example usage:
let paragraphs = $x("//p", XPathResult.ORDERED_NODE_SNAPSHOT_TYPE), i=1;
paragraphs.forEach(function(paragraph) { // Loop over every paragraph
paragraph.innerHTML = "This is paragraph #"+(i++);
});
let content=$x("//div[@class='center story']", XPathResult.FIRST_ORDERED_NODE_TYPE);
content.innerHTML="time to eat dinner!";
Note: When you specify a context node, you NORMALLY need to use a relative XPath expression. However, this function takes care of that technicality.