tags:

views:

1197

answers:

4

I have a Java maven project which includes XSLT transformations. I load the stylesheet as follows:

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

The stylesheet.xsl has a number of statements. These appear to be causing problems, when I try to run my unit tests I get the following errors:

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

The include statements in the XSLT are relative links

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

I have tried experimenting and changing these to the following - but I still get the error.

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

Any ideas? Any help much appreciated.

A: 

I had a problem similar to this once with relative paths in the XSLT.

If you can, try to put absolute paths in the XSLT - that should resolve the error.

An absolute path probably isn't preferable for the final version of the XSLT, but it should get you past the maven problem. Perhaps you can have two versions of the XSLT, one with absolute paths for maven and one with relative paths for whatever other tool it's being used with.

matt b
Matt, Thanks for the reply - this does fix the problem. However, the stylesheets are included in the jar file and so this solution would not work once the whole thing is packaged up.
will
+1  A: 

Set your DocumentBuilder object with an EntityResolver.

You'll have to extend EntityResolver class to resolve your external entities (footer.xsl and topbar.xsl).

bruno conde
+3  A: 

Solved my problem using a 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 (...

And assigning this with the TransformerFactory

tFactory.setURIResolver(new MyURIResolver());
will
A: 

There's an howto on the URIResolver here which might be of help for others. http://www.stylusstudio.com/xsllist/200210/post90010.html

Duveit