首页 > 解决方案 > Java Saxon 10.5 XSL 3 转换,未找到 href 文件

问题描述

我正在编写一个 Java 应用程序,该应用程序使用 Saxon-HE 10.5(作为 Maven 项目)使用 XSLT3 进行 XML 转换。我的 XSLT 工作表使用<xsl:import>(例如<xsl:import href="sheet1.xsl"/>)导入其他 XSLT 工作表。所有 XSLT 工作表都位于./src/main/resources. 但是,当我尝试运行该程序时,我收到了FileNotFound来自 Saxon 的异常,因为它正在项目基目录中查找文件。

s9api我认为有一些方法可以更改 Saxon 查找文件的位置,但是在使用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));
    }
}

标签: javaxmlxsltsaxonxslt-3.0

解决方案


Saxon 不知道样式表的基本 URI(它无法知道,因为您没有告诉它),因此它无法解析出现在xsl:import/@href.

通常我会建议在new StreamSource(). 但是,由于主样式表是使用 加载的getResourceAsStream(),我怀疑您想使用相同的机制加载辅助样式表模块,这可以通过URIResolverXsltCompiler对象上设置 a 来完成。


推荐阅读