I'm using Saxon 12 with Java 17 to transform an input XML document using XSLT, and it's working fine. The relevant code looks like this:
final Processor saxonProcessor = new Processor(false);
final XsltCompiler xsltCompiler = saxonProcessor.newXsltCompiler();
…
final XsltExecutable xsltStylesheet;
try (final InputStream xsltInputStream = new BufferedInputStream(…)) {
xsltStylesheet = xsltCompiler.compile(new StreamSource(xsltInputStream));
}
final Xslt30Transformer xsltTransformer = xsltStylesheet.load30();
final String text;
try (final InputStream xmlInputStream = new BufferedInputStream(…));
final StringWriter stringWriter = new StringWriter()) {
xsltTransformer.applyTemplates(new StreamSource(xmlInputStream), saxonProcessor.newSerializer(stringWriter));
text = stringWriter.toString();
}
//text now has XSLT output
The important part is xsltTransformer.applyTemplates(new StreamSource(xmlInputStream), …)
, which assumes that XSLT will read in an XML source file, parse that XML document, and then apply the XSLT stylesheet to it.
But it turns out that for each of my (tens of thousands of) XML documents, I want to perform various operations:
The Saxon XPath API seems to work on a parsed XML document, specifically a XdmItem
which I set using xpathSelector.setContextItem(document)
. (I haven't tried it but that's my best guess so far.) I would infer then that I could perform the first part (performing multiple XPath queries) on the same document without reparsing the document.
But then does Saxon XSLT require me to reparse the source document again each time? Is there a way to tell Saxon XSLT to apply the stylesheet to the XdmItem
I've already parsed, without parsing it again and again each time?
You can construct a tree representation of a source document by doing
DocumentBuilder builder = saxonProcessor.newDocumentBuilder();
XdmNode doc = builder.build(...);
You can call the Transformer.applyTemplates()
method to process an XdmNode
by noting that XdmNode
implements XdmValue
and there is a version of applyTemplates
that expects an XdmValue
.
Similarly, an XdmNode
is an XdmItem
and can therefore be passed directly to the XPath processor.