XPath in Action
While researching XML, I encountered an article titled "Using XPath in 2023" that provides a concise overview of XPath and introduces an elegant wrapper for document.evaluate, streamlining its implementation.
function* xpath(...args) {
let path, root = document;
if (args.length > 1) [root, path] = args;
else [path] = args;
const nodeIterator = document.evaluate(
path,
root,
null,
XPathResult.UNORDERED_NODE_ITERATOR_TYPE,
null,
);
for (
let node = nodeIterator.iterateNext();
node != null;
node = nodeIterator.iterateNext()
) {
yield node;
}
}
TypeScript types:
function xpath(path: string): Iterable<Node>; function xpath(root: Element, path: string): Iterable<Node>;
Example usage:
xpath('//body').next().value()
Potential alternative using plain document.evaluate :
function xpath(xpathExpression) {
const result = document.evaluate(
xpathExpression,
document,
null,
XPathResult.ANY_TYPE,
null
);
switch (result.resultType) {
case XPathResult.UNORDERED_NODE_ITERATOR_TYPE:
case XPathResult.ORDERED_NODE_ITERATOR_TYPE:
const nodes = [];
let node;
while ((node = result.iterateNext())) {
nodes.push(node);
}
return nodes;
case XPathResult.FIRST_ORDERED_NODE_TYPE:
case XPathResult.ANY_UNORDERED_NODE_TYPE:
return result.singleNodeValue;
case XPathResult.NUMBER_TYPE:
return result.numberValue;
case XPathResult.STRING_TYPE:
return result.stringValue;
case XPathResult.BOOLEAN_TYPE:
return result.booleanValue;
default:
return null;
}
}
Example usage:
xpath('//body')[0]