【发布时间】:2021-10-08 21:01:38
【问题描述】:
我正在编写一个使用 Saxon-HE 10.5(作为 Maven 项目)使用 XSLT3 进行 XML 转换的 Java 应用程序。
我的 XSLT 工作表使用 <xsl:import>(例如 <xsl:import href="sheet1.xsl"/>)导入其他 XSLT 工作表。所有 XSLT 工作表都位于 ./src/main/resources 内。但是,当我尝试运行该程序时,我收到了来自 Saxon 的 FileNotFound 异常,因为它正在项目基目录中查找文件。
我认为有一些方法可以更改 Saxon 查找文件的位置,但在使用 s9api API 时我无法找到实现此目的的方法。
这是我执行转换的 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));
}
}
【问题讨论】:
-
我猜你将需要使用docs.oracle.com/javase/8/docs/api/javax/xml/transform/stream/… 来确保Saxon 知道样式表的基本URI,Stream 上的StreamSource 不携带该信息。或者在编译器上设置一个URIResolversaxonica.com/html/documentation10/javadoc/net/sf/saxon/s9api/…。
-
stackoverflow.com/a/12453881/252228 可能有一个使用类加载器的 URIResolver 示例
标签: java xml xslt saxon xslt-3.0