You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中XSLT转换XML时无法找到href引用的functions.xslt文件

问题分析

你遇到的核心问题是:当前代码把deployments.xslt作为纯字符串加载到StringReader中,Transformer缺少上下文信息,无法解析相对路径的functions.xslt——尤其是打包成Jar包后,资源都在类路径下,相对路径的解析规则和本地文件系统完全不同,导致找不到依赖文件。

解决方案

方案1:设置StreamSource的SystemId(推荐)

当XSLT文件存放在Jar包的类路径下时,给StreamSource设置正确的systemId,让Transformer以此为基础解析相对路径的依赖文件。假设deployments.xslt和functions.xslt都在Jar包的/xslt/目录下,修改init方法:

private void init(String xslt) throws IOException, TransformerConfigurationException, AggregatorException {
    if (xslt == null || xslt.isEmpty()) {
        throw new AggregatorException("XSLT was null or empty. Unable to transform condensed model to yaml");
    }
    // 获取XSLT文件所在类路径的基础URI
    String baseUri = getClass().getResource("/xslt/").toExternalForm();
    StreamSource source = new StreamSource(new StringReader(xslt));
    // 设置systemId,让Transformer以此为根路径解析相对引用
    source.setSystemId(baseUri);
    transformer = factory.newTransformer(source);

    Security.addProvider(new BouncyCastleProvider()); 
}

注意:将/xslt/替换为你实际存放两个XSLT文件的类路径目录;如果文件直接在Jar根目录下,使用getClass().getResource("/").toExternalForm()即可。

方案2:内联functions.xslt代码

如果不想处理路径逻辑,直接把functions.xslt的全部内容复制到deployments.xslt中,替换掉<xsl:include href="functions.xslt"/>这一行。这样整个XSLT是单文件结构,没有外部依赖,打包后不会出现文件找不到的问题。

方案3:自定义URIResolver

实现URIResolver接口,让Transformer通过自定义逻辑加载依赖的XSLT文件,适合复杂的资源加载场景:

private void init(String xslt) throws IOException, TransformerConfigurationException, AggregatorException {
    if (xslt == null || xslt.isEmpty()) {
        throw new AggregatorException("XSLT was null or empty. Unable to transform condensed model to yaml");
    }
    // 自定义URI解析逻辑,从类路径加载依赖文件
    factory.setURIResolver(new URIResolver() {
        @Override
        public Source resolve(String href, String base) throws TransformerException {
            InputStream is = getClass().getResourceAsStream("/xslt/" + href);
            if (is == null) {
                throw new TransformerException("Could not find XSLT resource: " + href);
            }
            return new StreamSource(is);
        }
    });
    transformer = factory.newTransformer(new StreamSource(new StringReader(xslt)));

    Security.addProvider(new BouncyCastleProvider()); 
}

当Transformer遇到<xsl:include>标签时,会自动调用你实现的resolve方法,你可以在这里从类路径、数据库或其他自定义位置加载依赖文件。

内容的提问来源于stack exchange,提问作者Gene Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 15:06:38