Java Saxon 10.5 XSL 3 转换,找不到 href 文件
Java Saxon 10.5 XSL 3 Transformation, href file not found
我正在编写一个 Java 应用程序,它使用 XSLT3 和 Saxon-HE 10.5(作为 Maven 项目)执行 XML 转换。
我的 XSLT sheet 使用 <xsl:import>
(例如 <xsl:import href="sheet1.xsl"/>
)导入其他 XSLT sheet。所有 XSLT sheet 都位于 ./src/main/resources
内。但是,当我尝试 运行 程序时,我从 Saxon 得到一个 FileNotFound
异常,因为它正在项目基目录中查找文件。
我假设有一些方法可以改变 Saxon 寻找文件的位置,但我无法在使用 s9api
API.[=18 时找到如何实现这一点=]
这是我执行转换的 Java 代码:
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);
}
感谢任何帮助。
编辑:
我的解决方案基于@Michael Kay 的推荐:
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));
}
}
Saxon 不知道样式表的基本 URI(它无法知道,因为你没有告诉它),所以它无法解析 xsl:import/@href
中出现的相对 URI。
通常我会建议在 new StreamSource()
的第二个参数中提供一个基本 URI。但是,由于主样式表是使用 getResourceAsStream()
加载的,我怀疑您想使用相同的机制加载辅助样式表模块,这可以通过在 XsltCompiler
对象上设置 URIResolver
来完成.
我正在编写一个 Java 应用程序,它使用 XSLT3 和 Saxon-HE 10.5(作为 Maven 项目)执行 XML 转换。
我的 XSLT sheet 使用 <xsl:import>
(例如 <xsl:import href="sheet1.xsl"/>
)导入其他 XSLT sheet。所有 XSLT sheet 都位于 ./src/main/resources
内。但是,当我尝试 运行 程序时,我从 Saxon 得到一个 FileNotFound
异常,因为它正在项目基目录中查找文件。
我假设有一些方法可以改变 Saxon 寻找文件的位置,但我无法在使用 s9api
API.[=18 时找到如何实现这一点=]
这是我执行转换的 Java 代码:
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);
}
感谢任何帮助。
编辑: 我的解决方案基于@Michael Kay 的推荐:
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));
}
}
Saxon 不知道样式表的基本 URI(它无法知道,因为你没有告诉它),所以它无法解析 xsl:import/@href
中出现的相对 URI。
通常我会建议在 new StreamSource()
的第二个参数中提供一个基本 URI。但是,由于主样式表是使用 getResourceAsStream()
加载的,我怀疑您想使用相同的机制加载辅助样式表模块,这可以通过在 XsltCompiler
对象上设置 URIResolver
来完成.