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]