2008-11-03 57 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); 
});