17

I need to do an XSL transformation using Apache FOP and I had code like this:

//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 confirmed that it works when I have only one XSLT file, but in my project I have divided things into several XSLT files and joined them with the <xsl:import /> tag. With this configuration, I get a NullPointerException because it doesn't understand all the information stored in XSLT 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.

UPDATE

I've changed the code based on the answer given by Mads Hansen, but it still doesn't work. I have to include the XSLT slt files in the classpath, so I load the XSLT file with ClassLoader. 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?

4

3 に答える 3

20

私はちょうどそれを手に入れました、遅い答え(FOP 1.0でテストされました)------

必要なのは、次のように、ファクトリにURIリゾルバを設定することだけです。

TransformerFactory transFact = TransformerFactory.newInstance();
StreamSource xsltSource = new StreamSource(xsl);

// XXX for 'xsl:import' to load other xsls from class path
transFact.setURIResolver(new ClasspathResourceURIResolver());
Templates cachedXSLT = transFact.newTemplates(xsltSource);
Transformer transformer = cachedXSLT.newTransformer();


class ClasspathResourceURIResolver implements URIResolver {
  @Override
  public Source resolve(String href, String base) throws TransformerException {
    return new StreamSource(XXX.getClassLoader().getResourceAsStream(href));
  }
}

そして私のインポートxsl(したがって'imported.xsl'はクラスパスにあるはずです):

<xsl:import href="META-INF/companybusinesscredit/imported.xsl"/>
于 2012-09-17T06:06:10.363 に答える
13

XSLTをStreamSourceとしてロードし、 SystemIDを設定しない場合、プロセッサはXSLTが「どこに」あるかを認識せず、相対パスを解決できません。

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

StreamSourceへのパラメーターとしてシステムIDを提供することにより、commonFooter.xsltを探す場所をXSLTプロセッサーに指示します。このパラメーターがないと、プロセッサーがこのURIを解決できないときにエラーが発生する可能性があります。簡単な修正は、次のようにsetSystemId()メソッドを呼び出すことです。

// 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);
于 2010-09-13T12:19:31.193 に答える
2

私は Saxon 9.x を使用していますが、スタイルシート内でドキュメントを使用したときにまだ問題がありました。スタイルシートは正しく解決されましたが、jar ファイル内のスタイルシートと一緒にバンドルされた xml は、setSystemId を使用しても期待どおりにロードされませんでした。ファイルが見つからないという例外が発生しました。以下のコードを使用して、リゾルバーをカスタム コーディングする方が簡単でした。

JarfileResolver jarfileResolver = new JarfileResolver();
transformer.setURIResolver(jarfileResolver);


public class JarfileResolver implements URIResolver
{
    public Source resolve(String fileName, String base) throws TransformerException
    {
        URL url = getClass().getClassLoader().getResource(fileName);
        StreamSource jarFileSS = new StreamSource();

        try
        {
            InputStream jarfileIS = url.openStream();
            jarFileSS.setInputStream(jarfileIS);
        }
        catch(IOException ioExp)
        {
            throw new TransformerException(ioExp);
        }
        return jarFileSS;
    }
}
于 2012-12-07T19:35:37.737 に答える