我遇到了一个问题。我需要使用Java中的XSLT 2.0(SAXON-HE 9.8.0处理器)转换XML。在我的XSLT中,我使用functx的外部函数(通过导入)。
当两个文件(xslt map和.xsl文件与functx)在同一目录中时,一切正常。在我的.xsl中,正确导入了functx,它可以正常工作:
的xmlns:functx = “http://www.functx.com”
xsl:import href =“functx-package.xsl”
当两个文件在内存中作为String对象或InputStreams或其他什么时,有没有办法在我的.xsl映射中使用functx的外部函数?
我不能像以前那样将文件存储在一个目录中。
可能解决我的问题的唯一可能性是将functx文件粘贴到我的.xsl映射器中,但这是错误的解决方案 - [非常]不好的做法。
我该用什么:
提供具有逻辑的编译时URIResolver
public Source resolve(String href, String base) {
if (href.equals("functx-package.xsl")) {
return new StreamSource(new StringReader(functxAsString));
} else {
return null;
}
}
如果您使用s9api,编译时URIResolver是提供给XsltCompiler的编译时,如果您使用的是JAXP,则提供给TransformerFactory。
总结一下:
import documentation from Saxon
要正确使用此解析器,我们需要在TransformerFactory中设置它。比每个变换器在导入时捕获href并将文件与我们的.xsl文件匹配为字符串。我也使用outputURIResolver捕获输出并在内存中创建多个文件。 (有趣的用途outputURIResolver - link)
例:
在.xsl文件中:
<xsl:import href="functx-package.xsl"/>
<xsl:import href="functs-package.xsl"/>
在java中:
TransformerFactory tFactory = TransformerFactory.newInstance("net.sf.saxon.TransformerFactoryImpl", XMLviaXSLTransformer.class.getClassLoader());
tFactory.setURIResolver(new URIResolver() {
@Override
public Source resolve(String href, String base) {
if (href.equals("functx-package.xsl")) {
return new StreamSource(new StringReader(finalFunctsAsString));
} else if (href.equals("functs-package.xsl")) {
return new StreamSource(new StringReader(finalFunctxAsString));
} else {
return null;
}
}
});
Transformer transformer = tFactory.newTransformer(xsltMap);
StreamResult standardResult = new StreamResult(new ByteArrayOutputStream());
transformer.transform(xmlInput, standardResult);
谢谢Michael的帮助。这个URIResolver非常强大。