2008-11-03 56 views
5

我有一个包含XSLT转换的Java Maven项目。我加载样式表如下:转换由于xsl失败:include

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语句是相对链接

xsl:include href="footer.xsl" 
xsl:include href="topbar.xsl" 

我试图尝试和改变这些以下 - 但我仍然得到错误。

xsl:include href="xsl/footer.xsl" 
xsl:include href="xsl/topbar.xsl" 

任何想法?任何帮助非常感谢。

回答

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 (... 

而且随着

tFactory.setURIResolver(new MyURIResolver()); 
+0

不要忘记设置`documentBuilderFactory.setNamespaceAware(true)`。否则可能会阻止父样式表加载子样式表中的任何模板,从而导致ElemTemplateElement错误。 – 2014-01-31 16:53:01

0

我遇到过类似于XSLT中相对路径的问题。

如果可以,请尝试将绝对路径放入XSLT中 - 以解决错误。

对于XSLT的最终版本,绝对路径可能不是可取的,但它应该会让您通过maven问题。也许你可以有两个版本的XSLT,一个具有maven的绝对路径,另一个具有用于其他任何工具的相对路径。

+1

马特,感谢您的回复 - 这确实解决了问题。但是,样式表包含在jar文件中,所以一旦整个事情被打包,这个解决方案就不起作用。 – will 2008-11-03 14:29:34

1

将您的DocumentBuilder对象设置为EntityResolver

您将不得不扩展EntityResolver类来解析您的外部实体(footer.xsl和topbar.xsl)。

7

的URIResolver也可以在下面一个更直接的方式使用的TransformerFactory分配如下:

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()); 

或用拉姆达表达式:

transFact.setURIResolver((href, base) -> { 
    final InputStream s = cls.getResourceAsStream("xslts/" + href); 
    return new StreamSource(s); 
});