我们正在开发Java 8遗留软件。
我们使用XSLT转换以. html格式呈现. xml文件。
我们的问题是. xsl styleSheet文件导入了其他的. xsl文件。
(All下面的代码是dumbed下来,因为我不能给真正的代码...)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:import href="someTemplate.xsl"/>
<xsl:output method="html" encoding="UTF-8" indent="yes"/>
[...]
</xsl:stylesheet>
然后我们使用这个. xsl样式表转换我们的. xml数据源,并将net.sf.saxon.jaxp.SaxonTransformerFactory
作为我们的javax.xml.transform.Transformer
源。
Saxon pom依赖性:
<dependency>
<groupId>net.sf.saxon</groupId>
<artifactId>Saxon-HE</artifactId>
<version>9.7.0-14</version>
</dependency>
net.sf.saxon.jaxp.SaxonTransformerFactory
示例化如下:
TransformerFactoryImpl transformerFactory = new TransformerFactoryImpl();
Path targetFolderPath = <some Path>;
transformerFactory.setURIResolver((arg0, arg1) -> {
try
{
InputStream xslStream = Files.newInputStream(targetFolderPath.resolve(arg0));
return new StreamSource(xslStream);
}
catch (IOException e)
{
LOGGER.error(e.getLocalizedMessage(), e);
return null;
}
});
如果在try-with-resource中打开. xsl样式表。
try (InputStream xslStream = Files.newInputStream(Paths.get(pathToTheXslFile));)
{
Transformer transformer = transformerFactory.newTransformer(new StreamSource(xslStream));
transformer.transform(XmlData, new StreamResult(destFile));
}
catch (IOException | TransformerException e)
{
[some logs...]
}
我们的问题是,转换似乎打开了由. xsl样式表导入的文件,而没有关闭它。
这导致在Linux操作系统上工作时出现“打开文件过多错误”。
基本上我们完全被这个问题难住了,因为javax.xml.transform.Transformer
不提供任何自动关闭选项,我们似乎没有任何访问打开的文件。
我们想到的是做一些自定义代码来通过Linux命令行强制关闭文件。
- 编辑**:
阅读代码后,我的最新更新的描述,我现在看到它...
在为TransformerFactory创建URIResolver时,我们没有实现Try-with-resource。
我会做出改变,测试它,然后关闭问题,如果它确实工作(它应该...;)).
Thx的评论。
- EDIT2**:
将try-with-resource添加到URIResolver lambda表达式中会导致net.sf.saxon.s9api.SaxonApiException: I/O error reported by XML parser processing null: null
这是因为一旦返回StreamSource
,用于创建StreamSource
的InputStream
就会关闭,从而使其变得无用。
2条答案
按热度按时间u5i3ibmn1#
看起来像bug https://saxonica.plan.io/issues/3401
这在Saxon 9.7.0.21和更高版本中得到了修复。
保持最新是一个好主意,如果不是主要版本,至少保持维护版本的最新。Saxon 9.7可以追溯到2017年。
在bug条目中还有一个链接,指向我用于诊断的工具--你可能会发现这很有帮助。
enxuqcxy2#
感谢您的所有输入,我们发现了问题并提出了更正(确实接近@MichaelKay评论的建议)。
基本上,我们实现了自己的
URIResolver
,它实现了一个close()
方法,然后我们将其调用到finally
子句中。CustomUriResolver:
XSLT转换的用法: