I'm writing a Java application that does a XML transformation using XSLT3, using Saxon-HE 10.5 (as a Maven project).
My XSLT sheet imports other XSLT sheets, using <xsl:import>
(e.g. <xsl:import href="sheet1.xsl"/>
). All of the XSLT sheets are located inside ./src/main/resources
. However, when I try to run the program, I get a FileNotFound
Exception from Saxon, since it is looking for the files at the project base directory.
I assume there is some way to change where Saxon is looking for the files, but I was not able to find out how to achieve this when using the s9api
API.
Here's my Java code performing the transformation:
public void transformXML(String xmlFile, String output) throws SaxonApiException, IOException, XPathExpressionException, ParserConfigurationException, SAXException {
Processor processor = new Processor(false);
XsltCompiler compiler = processor.newXsltCompiler();
XsltExecutable stylesheet = compiler.compile(new StreamSource(this.getClass().getClassLoader().getResourceAsStream("transform.xsl")));
Serializer out = processor.newSerializer(new File(output));
out.setOutputProperty(Serializer.Property.METHOD, "text");
Xslt30Transformer transformer = stylesheet.load30();
transformer.transform(new StreamSource(new File(xmlFile)), out);
}
Any help is appreciated.
Edit: My solution based on @Michael Kay's recommendation:
public void transformXML(String xmlFile, String output) throws SaxonApiException, IOException, XPathExpressionException, ParserConfigurationException, SAXException {
Processor processor = new Processor(false);
XsltCompiler compiler = processor.newXsltCompiler();
compiler.setURIResolver(new ClasspathResourceURIResolver());
XsltExecutable stylesheet = compiler.compile(new StreamSource(this.getClass().getClassLoader().getResourceAsStream("transform.xsl")));
Serializer out = processor.newSerializer(new File(output));
out.setOutputProperty(Serializer.Property.METHOD, "text");
Xslt30Transformer transformer = stylesheet.load30();
transformer.transform(new StreamSource(new File(xmlFile)), out);
}
}
class ClasspathResourceURIResolver implements URIResolver
{
@Override
public Source resolve(String href, String base) throws TransformerException {
return new StreamSource(this.getClass().getClassLoader().getResourceAsStream(href));
}
}