Skip to content

Instantly share code, notes, and snippets.

@jmakeig
Last active January 31, 2020 23:50
Show Gist options
  • Select an option

  • Save jmakeig/091f8e4bfcb76840b1b2e221276bc791 to your computer and use it in GitHub Desktop.

Select an option

Save jmakeig/091f8e4bfcb76840b1b2e221276bc791 to your computer and use it in GitHub Desktop.
Database-wide XPath evaluation in JavaScript in MarkLogic
/**
* @param {string} path
* @param {object} [bindings]
* @param {string | Iterable<string>} [collection]
* @return {Sequence<Node>}
*/
const xpath = (function _memo() {
function isIterable(itr, ignoreStrings = false) {
if ('string' === typeof itr) return !ignoreStrings;
return Boolean(itr && itr[Symbol.iterator]);
}
function join(itr) {
const quote = str => (str ? "'" + str + "'" : '');
if (isIterable(itr, true)) {
return `(${Array.from(itr)
.map(quote)
.join(',')})`; // Parens for an XPath Sequence
}
return quote(itr);
}
const node = new NodeBuilder().addNull().toNode(); // Total hack
return function xpath(path, bindings, collection, options = { plan: false }) {
const expression = `collection(${join(collection)})${
'/' === path ? '' : path
}`; // Special case: `collection()/` is not valid XPath
if (options && options.plan) {
return xdmp.xqueryEval(
`xdmp:plan(${expression}${
'number' === typeof options.plan ? `,${options.plan}` : ``
})`
);
}
return Node.prototype.xpath.call(node, expression, bindings);
};
})();
// Example:
xpath('/'); // Sequence
xpath('/', {}, undefined, { plan: true }); // XMLNode
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment