Reputation: 467
const node = document.createElement('div');
node.innerHTML = "<p>Text 1</p>"
For this JS HTMLElement, how should I run an XPath against it using SaxonJS?
const res = saxonJs.XPath.evaluate('//p', node);
Has error Context item for '/' must be a node
const res = saxonJs.XPath.evaluate('*', node);
Has error Context item for child axis is not a node - supplied:HashTrie map{}
MORE DETAILS: The ultimate goal is to run XPath 3.0 against an HTML DOM (parsed from a string) in Node JS, so I'm open to using other modules or methods
Upvotes: 1
Views: 248
Reputation: 167436
Inside the browser there is always one sole DOM implementation that both SaxonJS and the browser use so there you can indeed use HTML DOM document and nodes as context items, even if not officially supported in e.g. https://www.saxonica.com/saxon-js/documentation2/index.html#!api/getResource (by adding html
as a possible type
).
const html = `<p>This is a test.
<p>This is a test.
<ul>
<li>a</li>
<li>1</li>
<li>b</li>
</ul>`;
const htmlDoc = new DOMParser().parseFromString(html, 'text/html');
const alphabeticLIElements = SaxonJS.XPath.evaluate("//li[matches(., '\\p{L}+')]", htmlDoc, { xpathDefaultNamespace : 'http://www.w3.org/1999/xhtml' });
console.log(alphabeticLIElements);
<script src="https://www.saxonica.com/saxon-js/documentation2/SaxonJS/SaxonJS2.rt.js"></script>
Inside Node.js, things, as far as I understand, are different, the SaxonJS internalizes some third party DOM implementation (which by now might be compatible to support text/html
parsing) but doesn't expose any method or way for HTML parsing.
I did a feature request https://saxonica.plan.io/issues/5302 (or two) on that some while ago but so far there has been no new release on the 2.x branch to implement or expose that.
So I afraid, unless you find a way through the Node.js module structure to access the internalized DOM implementation, there is currently no way to achieve that.
The official way, once implemented/exposed, I think would be along the lines of
const SaxonJS = require("saxon-js");
const html = `<p>This is a test.
<p>This is a test.
<ul>
<li>a</li>
<li>1</li>
<li>b</li>
</ul>`;
SaxonJS.getResource({ type : 'html', text: html }).then(htmlDoc => {
console.log(htmlDoc);
const alphabeticLIElements = SaxonJS.XPath.evaluate("//li[matches(., '\\p{L}+')]", htmlDoc, { xpathDefaultNamespace : 'http://www.w3.org/1999/xhtml' });
console.log(alphabeticLIElements);
}).catch(err => console.log(err));
Upvotes: 2