2010-08-18 10 views
5

Die Top-Antwort auf diese Frage eine Technik beschreibt eine effiziente XSLT-Pipeline in Java implementieren:Effiziente XSLT-Pipeline, mit params, in Java

Efficient XSLT pipeline in Java (or redirecting Results to Sources)

Leider, während Transformator eine API zu belichten für die Einstellung scheint XSLT-Parameter, scheint dies keine Auswirkungen zu haben. Zum Beispiel habe ich den folgenden Code:

Transformer.java

import javax.xml.transform.sax.SAXTransformerFactory; 
import javax.xml.transform.Templates; 
import javax.xml.transform.sax.TransformerHandler; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.stream.StreamResult; 
import javax.xml.transform.stream.StreamSource; 
import javax.xml.transform.sax.SAXResult; 
import javax.xml.transform.Transformer; 
import java.io.File; 
public class MyTransformer { 
    public static void main(String[] args) throws javax.xml.transform.TransformerConfigurationException, javax.xml.transform.TransformerException{ 
     SAXTransformerFactory stf = (SAXTransformerFactory)TransformerFactory.newInstance(); 

     // These templates objects could be reused and obtained from elsewhere. 
     Templates templates1 = stf.newTemplates(new StreamSource(new File("MyStylesheet1.xslt"))); 
     Templates templates2 = stf.newTemplates(new StreamSource(new File("MyStylesheet2.xslt"))); 

     TransformerHandler th1 = stf.newTransformerHandler(templates1); 
     TransformerHandler th2 = stf.newTransformerHandler(templates2); 

     th1.setResult(new SAXResult(th2)); 
     th2.setResult(new StreamResult(System.out)); 

     Transformer t = stf.newTransformer(); 

      //SETTING PARAMETERS HERE 
     t.setParameter("foo","this is from param 1"); 
     t.setParameter("bar","this is from param 2"); 

     t.transform(new StreamSource(new File("in.xml")), new SAXResult(th1)); 

     // th1 feeds th2, which in turn feeds System.out. 
    } 
} 

MyStylesheet1.xslt

<?xml version="1.0"?> 
<stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:foo="urn:foo" version="1.0"> 
    <output method="xml"/> 

    <param name="foo"/> 

    <template match="@*|node()"> 
     <copy> 
      <apply-templates select="@*|node()"/> 
     </copy> 
    </template> 

    <template match="foo:my/foo:hello"> 
     <copy> 
      <foo:world> 
       foo is : <value-of select="$foo"/> 
      </foo:world> 
     </copy> 

    </template> 
</stylesheet> 

MyStylesheet2.xslt

<?xml version="1.0"?> 
<stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:foo="urn:foo" version="1.0"> 
    <output method="xml"/> 

    <param name="bar"/> 

    <template match="@*|node()"> 
     <copy> 
      <apply-templates select="@*|node()"/> 
     </copy> 
    </template> 

    <template match="foo:my/foo:hello/foo:world"> 
     <copy> 
      <apply-templates select="@*|node()"/> 

      <attribute name="attr"> 
       <value-of select="$bar"/> 
      </attribute> 
     </copy> 

    </template> 
</stylesheet> 

in.xml

<my xmlns="urn:foo"> 
    <hello/> 
</my> 

die mir die folgende Ausgabe gibt:

<?xml version="1.0" encoding="UTF-8"?><my xmlns="urn:foo"> 
     <hello><foo:world xmlns:foo="urn:foo">foo is : </foo:world></hello> 
</my> 

Wie Sie foo sehen: Welt/@ attr ist leer, und die Textinhalte von foo: Welt sagt "foo ist:". Das erwartete Verhalten besteht darin, dass sie mit den Parametern gefüllt sein sollten, die an die setParameter-Methode übergeben wurden.

Gibt es eine Möglichkeit, XSL-Transformationsparameter mithilfe dieser Technik festzulegen. Wenn nicht, könnte jemand eine alternative Technik zum effizienten Transformieren von Stylesheets in Java empfehlen, so dass auch XSLT-Parameter gesetzt werden können?

Antwort

6

Das Problem ist, dass jedem TransformerHandler ein separater Transformer zugeordnet ist. Es gibt ein Problem mit Ihrer zweiten Vorlage, aber da dies ein Beispiel ist, ist das egal. Sie wollen:

//SETTING PARAMETERS HERE 
th1.getTransformer().setParameter("foo","this is from param 1"); 
th2.getTransformer().setParameter("bar","this is from param 2"); 

Beachten Sie, dass Sie nicht auch einen dritten Transformator erstellen müssen, können Sie einfach die Kette auf th1.getTransformer verwandeln start()

0

bis zur letzten Note zusammen. Aufruf von transform() auf th1.getTransformer() mit dem Ergebnis wieder auf th1 zeigt, ist nicht korrekt. Es wird zweimal verarbeitet. mit neuen Transformer() wie im ursprünglichen Beitrag gezeigt ist der richtige Weg.

t.transform(new StreamSource(new File("in.xml")), new SAXResult(th1));