# XSL - relative Pfadangabe



## sina.die (23. Aug 2010)

Sorry!
Ich denke, es kann eigentlich nicht so schwer sein, aber scheinbar bin ich zu blöde zum googlen, um das richtige zu funden.

Ich baue mir in einer XSL-Datei (durch FOP) eine PDF-Seite auf. In einem kleinen Teil dieses PDFs möchte ich HTML anzeigen also benutze ich auch mehrere Templates, um das HTML zu übersetzen.
Soweit so gut.
Nun dachte ich mir: Ist ja blöd, wenn ich den allgemeinen HTML-Übersetzungskram mit meinem speziellen PDF-Generiere in einer Datei stehen hab. Da lagere ich doch den allgemeinen HTML-Teil aus, um das Ganze ein bisschen übersichtlicher zu machen.

Das funktioniert auch lokal ganz toll, aber ich gebe dabei so viel Pfad von der zu importierenden Stylesheet-Datei an, dass ich Zweifel habe, dass das noch funktioniert, wenn das Ganze mal deployed wird. Eigentlich sind auch beide Dateien im gleichen Package - ich hätte gedacht, dass ich dann auf den Pfad verzichten kann und nur den Namen angeben muss, aber das geht nicht


			
				etwas gekürzt hat gesagt.:
			
		

> javax.xml.transform.TransformerConfigurationException
> Caused by: javax.xml.transform.TransformerConfigurationException: javax.xml.transform.TransformerException: javax.xml.transform.TransformerException: IO-Ausnahme bei Stylesheet-Datei: html2fo.xsl
> Caused by: java.io.FileNotFoundException: D:\PROJEKT_IDE\html2fo.xsl (Das System kann die angegebene Datei nicht finden)



Der momentane Pfad sieht so aus:
[XML]<xsl:import href="projects/Middleware/src/main/resources/la/projektname/middleware/pdf/html2fo.xsl"/>[/XML]
"projects" ist mein Workspace-Ordner. "Middleware" ist das Java-Projekt.

Weiß da jemand Rat?

Viele Grüße,
Sina


----------



## fkh (24. Aug 2010)

sina hat gesagt.:


> Das funktioniert auch lokal ganz toll, aber ich gebe dabei so viel Pfad von der zu importierenden Stylesheet-Datei an, dass ich Zweifel habe, dass das noch funktioniert, wenn das Ganze mal deployed wird. Eigentlich sind auch beide Dateien im gleichen Package - ich hätte gedacht, dass ich dann auf den Pfad verzichten kann und nur den Namen angeben muss, aber das geht nicht
> [..]
> Weiß da jemand Rat?



Hallo Sina,

du brauchst dazu einen URIResolver (Java Platform SE 6). Wenn du das ganze über JAXP löst, dann schau dir noch TransformerFactory (Java Platform SE 6) an. Damit kannst du einen eigenen URIResolver (muss das URIResolver interface implementieren) definieren, der dann den Pfad auflösen kann. Ein einfaches Bsp wäre, über getClass().getRessourceAsStream(..) dir nen InputStream zu holen und den anschließend über return new StreamSource(is) zurückzuliefern.

Gruß
fkh


----------



## sina.die (24. Aug 2010)

Danke, da hab ich nen Ansatz was isch machen muss!
Weiß noch nicht, ob ich erleichtert bin, dass es doch nicht trivial ist oder enttäuscht. ;-)


----------



## sina.die (24. Aug 2010)

Ach nee halt, ich sehe gerade sowas in der Art passiert ja schon:


```
TransformerFactory tFactory = TransformerFactory.newInstance();

            // Setup a buffer to obtain the content length
            ByteArrayOutputStream out = new ByteArrayOutputStream();

            // Setup Transformer (Stylesheet und Parameters)
            InputStream xsltStream = getClass().getClassLoader().getResourceAsStream(styleSheetName);
            if (xsltStream == null) {
                log.error("xsl not found.");
            }
            Source xsltSrc = new StreamSource(xsltStream);
            Transformer transformer = tFactory.newTransformer(xsltSrc);
```

Die hier geladene .xsl-Datei ist ja auch nicht das Problem, sondern die.xsl, die diese .xsl importen will.
Oder hab ichs nun falsch verstanden?


----------



## fkh (24. Aug 2010)

sina hat gesagt.:


> Ach nee halt, ich sehe gerade sowas in der Art passiert ja schon:
> 
> 
> ```
> ...



Hallo,

ja, da hast du jetzt etwas falsch verstanden.

Zuerstmal brauchst du nen URIResolver, der könnte in etwa so aussehen.

[Java]
package jaxp;

import java.io.InputStream;

import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamSource;

public class MyUriResolver implements URIResolver {
    public Source resolve(String href, String base) throws TransformerException {
        if ("projects/Middleware/src/main/resources/la/projektname/middleware/pdf/html2fo.xsl"
                .equals(href)) {
// ich geh mal davon aus, dass src/main/resources bei dir als Source Folder fungiert, ansonsten Pfad anpassen
            InputStream is = getClass().getResourceAsStream("/la/projektname/middleware/pdf/html2fo.xsl");
            return new StreamSource(is);
        } else
            return null; // das hier entsprechend abändern, evtl fallback auf irgendwas
    }
}
[/Java]

Dieser URIResolver ist dafür zuständig, den Aufruf "umzubiegen". Damit der jetzt auch von deinem Transformer genutzt werden kann, musst du noch folgendes bei der TransformerFactory eintragen (Zeile 2).

[Java]
    TransformerFactory factory = TransformerFactory.newInstance();
    factory.setURIResolver(new MyUriResolver());
    Transformer transformer = factory.newTransformer(xsl);
[/Java]

Ich habe den Code jetzt nicht ganz getestet, aber er sollte so in etwa passen.


----------



## sina.die (30. Aug 2010)

Ach, ich hab mich ganz vergessen zurückzumelden. Es ging nun, danke!


----------

