我有一个包含XSLT转换的Java maven项目。我按如下方式加载样式表:
TransformerFactory tFactory = TransformerFactory.newInstance();
DocumentBuilderFactory dFactory = DocumentBuilderFactory
.newInstance();
dFactory.setNamespaceAware(true);
DocumentBuilder dBuilder = dFactory.newDocumentBuilder();
ClassLoader cl = this.getClass().getClassLoader();
java.io.InputStream in = cl.getResourceAsStream("xsl/stylesheet.xsl");
InputSource xslInputSource = new InputSource(in);
Document xslDoc = dBuilder.parse(xslInputSource);
DOMSource xslDomSource = new DOMSource(xslDoc);
Transformer transformer = tFactory.newTransformer(xslDomSource);
stylesheet.xsl有许多语句。这些似乎导致问题,当我尝试运行我的单元测试时,我得到以下错误:
C:\Code\workspace\app\dummy.xsl; Line #0; Column #0; Had IO Exception with stylesheet file: footer.xsl
C:\Code\workspace\app\dummy.xsl; Line #0; Column #0; Had IO Exception with stylesheet file: topbar.xsl
XSLT中的include语句是相对链接
xsl:include href="footer.xsl"
xsl:include href="topbar.xsl"
我尝试过尝试并将这些更改为以下内容 - 但我仍然收到错误。
xsl:include href="xsl/footer.xsl"
xsl:include href="xsl/topbar.xsl"
有什么想法吗?任何帮助非常感谢。
答案 0 :(得分:11)
使用URIResolver解决了我的问题。
class MyURIResolver implements URIResolver {
@Override
public Source resolve(String href, String base) throws TransformerException {
try {
ClassLoader cl = this.getClass().getClassLoader();
java.io.InputStream in = cl.getResourceAsStream("xsl/" + href);
InputSource xslInputSource = new InputSource(in);
Document xslDoc = dBuilder.parse(xslInputSource);
DOMSource xslDomSource = new DOMSource(xslDoc);
xslDomSource.setSystemId("xsl/" + href);
return xslDomSource;
} catch (...
并使用TransformerFactory
进行分配tFactory.setURIResolver(new MyURIResolver());
答案 1 :(得分:8)
URIResolver也可以更直接的方式使用,如下所示:
class XsltURIResolver implements URIResolver {
@Override
public Source resolve(String href, String base) throws TransformerException {
try{
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("xslts/" + href);
return new StreamSource(inputStream);
}
catch(Exception ex){
ex.printStackTrace();
return null;
}
}
}
将URIResolver与TransformerFactory一起使用,如下所示:
TransformerFactory transFact = TransformerFactory.newInstance();
transFact.setURIResolver(new XsltURIResolver());
或者使用lambda表达式:
transFact.setURIResolver((href, base) -> {
final InputStream s = this.getClass().getClassLoader().getResourceAsStream("xslts/" + href);
return new StreamSource(s);
});
答案 2 :(得分:1)
使用EntityResolver设置DocumentBuilder对象。
您必须扩展EntityResolver类以解析外部实体(footer.xsl和topbar.xsl)。
答案 3 :(得分:0)
我在XSLT中遇到了与此类似的问题。
如果可以的话,尝试在XSLT中放置绝对路径 - 这应该可以解决错误。
绝对路径可能不适合XSLT的最终版本,但它应该让你超越maven问题。也许你可以有两个版本的XSLT,一个版本具有maven的绝对路径,另一个版本具有与其一起使用的任何其他工具的相对路径。