java - 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));
}
}
解决方案
Saxon 不知道样式表的基本 URI(它无法知道,因为您没有告诉它),因此它无法解析出现在xsl:import/@href
.
通常我会建议在new StreamSource()
. 但是,由于主样式表是使用 加载的getResourceAsStream()
,我怀疑您想使用相同的机制加载辅助样式表模块,这可以通过URIResolver
在XsltCompiler
对象上设置 a 来完成。
推荐阅读
- c# - 在自动化运行期间阻止光标移动
- node.js - 如何在axios中导入文件名?
- php - 如何在 php 中使用 html2canvas 中的代理在 div 中加载外部图像
- c++11 - 特征:用 unaryExpr 返回指针
- asp.net-core - Hangfire 作业未在我的 Asp .Net Core 站点上运行
- javascript - 如何在 React 中将状态数据从父级更改为子级后立即获取状态数据?
- javascript - 一些网站想在我的 chrome 中自动选择输入单选
- php - Serverload 使用带有 mail() 的自己的 postfix 与带有外部 smtp 的 phpmailer
- android - Android 警报对话框中的 EditText
- php - 如何以两种语言根据运输类别显示产品的可用性