views:

138

answers:

1

I've updated the question below

Hello,

I need to do a XSL transformation using Apache FOP and I have a code like this one:

    //Setup FOP
    Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out);
    //Setup Transformer
    Source xsltSrc = new StreamSource(new File(xslPath));
    Transformer transformer = tFactory.newTransformer(xsltSrc);

    //Make sure the XSL transformation's result is piped through to FOP
    Result res = new SAXResult(fop.getDefaultHandler());
    //Setup input
    Source src = new StreamSource(new File(xmlPath));
    //Start the transformation and rendering process
    transformer.transform(src, res);

where xslPath is the path where my xslt file is stored.

I have checked that it works when I have only one xslt file, but in my project I have divided it into several xslt files joining them with the <xsl:import /> tag. With this configuration I get a NullPointerException because it doesn't understand all the information stored in the xslt file because it's distributed over different files.

I wonder if there's any way to load all these files in the Source xsltSrc variable so all the XSL information is available .

Thank you very much.

UPDATE

I've changed the code with the idea given by Mads Hansen, but it still doesn't work. I have to include the xslt files in the classpath so I load the xslt file with ClassLoader and I've checked that the url has the correct path when executing url.toExternalForm(). This is my new piece of code:

ClassLoader cl = this.getClass().getClassLoader();
String systemID = "resources/xslt/myfile.xslt";
InputStream in = cl.getResourceAsStream(systemID);
URL url = cl.getResource(systemID);
Source source = new StreamSource(in);
source.setSystemId(url.toExternalForm());
transformer = tFactory.newTransformer(source);

It finds and loads myfile.xslt but it still doesn't resolve the relative paths to the other xslt files.

What am I doing wrong?

Thanks.

+1  A: 

When you load an XSLT as a StreamSource and do not set a SystemID, the processor doesn't know "where" the XSLT is and cannot resolve relative paths.

http://www.onjava.com/pub/a/onjava/excerpt/java_xslt_ch5/index.html?page=5

By providing a system identifier as a parameter to the StreamSource, you are telling the XSLT processor where to look for commonFooter.xslt. Without this parameter, you may encounter an error when the processor cannot resolve this URI. The simple fix is to call the setSystemId( ) method as follows:

// construct a Source that reads from an InputStream
Source mySrc = new StreamSource(anInputStream);
// specify a system ID (a String) so the 
// Source can resolve relative URLs
// that are encountered in XSLT stylesheets
mySrc.setSystemId(aSystemId);
Mads Hansen
thanks for your answer, but it doesn't seem to solve my problem, though your answer makes sense. I've updated my question with my changes in the code.
Javi
You may need to obtain an absolute path for your SystemID. Unless you know where it will be resolving the relative path "from". Try converting that relative path into an absolute path with something like: `String xsltSystemId = new File(systemID).toURL().toExternalForm( );` or `String xsltSystemId = new File(relativePath).getAbsolutePath();`
Mads Hansen
thanks, I had already though in that and I had checked that When I do url.toExternalForm() it gets an absolute path. But I don't know where's the problem now.
Javi
Is it possible that your import statements are not correct? (case sensitivity of filenames, incorrect filename, incorrect path, etc). Could there be an issue with file permissions? Try running your stylesheet through other means(in an IDE like Xselerator, oXygen, XML spy, or commandline invocation of Saxon, etc).
Mads Hansen
@Mads Hansen No my xslt files are correct. I can do the xsl conversion executing a command in the console without any problem. It's very weird. +1 for your answer because of your effort though I haven't solve the problem yet.
Javi