Als Teil von Cocoon ist auch der XSL-Formatierer Fop von James Tauber auf dem Apache-Server zu finden. Dieses Programm gestattet die dynamische Erzeugung von PDF-Dokumenten aus XML. Wie bereits früher erläutert, ist dazu eine Transformation in die XML-Form nötig, die die Formatierungsobjekte beschreibt (XSL-FO). Natürlich ist das wieder eine Aufgabe für XSLT. Da es sich letzlich nur um eine andere Ausgabe-DTD handelt, können wir uns die langen Vorreden sparen und gleich in das Beispiel einsteigen. Einmal mehr musste die oben gezeigte Notiz herhalten, mit einer kleinen Änderung. Da die Ausgabe nun PDF sein soll und nicht HTML, ändert sich die Verknüpfung mit dem Stylesheet in folgender Weise:
<?xml version="1.0"?> <?cocoon-process type="xslt"?> <?xml-stylesheet href="notiz2fo.xslt" type="text/xsl"?> <notiz> <titel>Termine</titel> <autor>Weihnachtsmann</autor> <datum>24.12.2000</datum> <absatz>Nicht vergessen: <wichtig>Geschenke austeilen</wichtig> </absatz> <absatz> ... </absatz> </notiz>
Hier tritt ein neues Stylesheet in Aktion, das in der Datei notiz2fo.xslt steht. Es transformiert Notizen in die XSL-FO-Form. Folgendes Listing zeigt notiz2fo.xslt:
<?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"> <!-- © 2000 Stefan Mintert --> <!-- ====================================================== --> <!-- Template fuer Root-Element 'notiz' --> <xsl:template match="notiz"> <xsl:processing-instruction name="cocoon-format">type="text/xslfo"</xsl:processing-instruction> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master page-master-name="one" page-height="15cm" page-width="21cm" margin-left="2cm" margin-right="2cm"> <fo:region-body margin-top="50pt" margin-bottom="50pt"/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence> <fo:sequence-specification> <fo:sequence-specifier-repeating page-master-first="one" page-master-repeating="one"/> </fo:sequence-specification> <fo:flow font-size="14pt" line-height="18pt"> <xsl:apply-templates select="titel"/> <fo:table space-before.optimum="6pt"> <fo:table-column column-width="2cm"/> <fo:table-column column-width="10cm"/> <fo:table-body> <xsl:apply-templates select="autor|datum|absatz"/> </fo:table-body> </fo:table> <fo:block text-align="justified" space-before.optimum="30pt"> Copyright © 2000 Stefan Mintert. Dieses Beispiel stammt aus der zweiten Auflage von »XML in der Praxis«. <fo:inline font-style="italic">http://www.mintert.com/xml/</fo:inline> </fo:block> </fo:flow> </fo:page-sequence> </fo:root> </xsl:template> <!-- ====================================================== --> <!-- Template fuer Elementtyp 'titel' --> <xsl:template match="titel"> <fo:block text-align="centered" font-size="24pt" font-weight="bold" line-height="28pt"><xsl:apply-templates/> </fo:block> </xsl:template> <!-- ====================================================== --> <!-- ====================================================== --> <!-- Template fuer Elementtyp 'autor' --> <xsl:template match="autor"> <fo:table-row space-before.optimum="6pt"> <fo:table-cell> <fo:block text-align="right" font-style="italic">von</fo:block> </fo:table-cell> <fo:table-cell> <fo:block text-align="left"><xsl:apply-templates/></fo:block> </fo:table-cell> </fo:table-row> </xsl:template> <!-- ====================================================== --> <!-- ====================================================== --> <!-- Template fuer Elementtyp 'datum' --> <xsl:template match="datum"> <fo:table-row space-before.optimum="6pt"> <fo:table-cell> <fo:block text-align="right" font-style="italic">für den</fo:block> </fo:table-cell> <fo:table-cell> <fo:block text-align="left"><xsl:apply-templates/></fo:block> </fo:table-cell> </fo:table-row> </xsl:template> <!-- ====================================================== --> <!-- ====================================================== --> <!-- Template fuer Elementtyp 'restzeit' --> <xsl:template match="restzeit"> <fo:table-row space-before.optimum="6pt"> <fo:table-cell> <fo:block text-align="right" font-style="italic">in</fo:block> </fo:table-cell> <fo:table-cell> <fo:block text-align="left"><xsl:apply-templates/></fo:block> </fo:table-cell> </fo:table-row> </xsl:template> <!-- ====================================================== --> <!-- ====================================================== --> <!-- Template fuer Elementtyp 'absatz' --> <xsl:template match="absatz"> <fo:table-row space-before.optimum="6pt"> <fo:table-cell> <fo:block text-align="right"></fo:block> </fo:table-cell> <fo:table-cell> <fo:block text-align="left" space-after.optimum="6pt"><xsl:apply-templates/></fo:block> </fo:table-cell> </fo:table-row> </xsl:template> <!-- ====================================================== --> <!-- ====================================================== --> <!-- Template fuer Elementtyp 'wichtig' --> <xsl:template match="wichtig"> <fo:inline-sequence font-weight="bold"> <xsl:apply-templates/> </fo:inline-sequence> </xsl:template> <!-- ====================================================== --> </xsl:stylesheet>
Aus dem XSLT-Stylesheet kann man fast unmittelbar die spätere XSL-FO-Ausgabe ablesen. Wichtige globale Festlegungen sind die Seitenmaße (page-height="15cm" und page-width="21cm") sowie die Schriftgröße (font-size="14pt" und line-height="18pt"). Sie werden bei Behandlung des Wurzelelements (xsl:template match="notiz") ausgegeben. Der Textinhalt wird getrennt in Titel (xsl:apply-templates select="titel") und sonstigen Elementen (xsl:apply-templates select="autor|datum|absatz") verarbeitet. Auch die Templates für die Kindelemente von notiz sind einfach zu verstehen. Der Titel wird groß, fett und zentriert gesetzt (font-size="24pt", font-weight="bold", text-align="centered"). Für die anderen Elemente wird jeweils eine eigene Tabellenzeile erzeugt. Was die XSLT-Maschine daraus macht, ist im nächsten Listing zu sehen.
sm@brown{558}: java org.apache.xalan.xslt.Process -in notiz3.xml -xsl notiz2fo.xslt -out notiz3.fo ========= Parsing file:/home/sm/cocoon/dokumente/demo/notiz2fo.xslt ========== Parse of file:/home/sm/cocoon/dokumente/demo/notiz2fo.xslt took 790 milliseconds ========= Parsing notiz3.xml ========== Parse of notiz3.xml took 108 milliseconds encoding not supported: UTF8, using Java 8859_1 ============================= Transforming... transform took 53 milliseconds XSLProcessor: done sm@brown{559}: cat notiz3.fo <?cocoon-format type="text/xslfo"?><fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set><fo:simple-page-master margin-right="2cm" margin-left="2cm" page-width="21cm" page-height="15cm" page-master-name="one"><fo:region-body margin-bottom="50pt" margin-top="50pt"/></fo:simple-page-master></fo:layout-master-set> <fo:page-sequence><fo:sequence-specification><fo:sequence-specifier-repeating page-master-repeating="one" page-master-first="one"/></fo:sequence-specification><fo:flow line-height="18pt" font-size="14pt"><fo:block line-height="28pt" font-weight="bold" font-size="24pt" text-align="centered">Termine</fo:block><fo:table space-before.optimum="6pt"><fo:table-column column-width="2cm"/><fo:table-column column-width="10cm"/><fo:table-body><fo:table-row space-before.optimum="6pt"><fo:table-cell><fo:block font-style="italic" text-align="right">von</fo:block></fo:table-cell><fo:table-cell><fo:block text-align="left">Weihnachtsmann</fo:block></fo:table-cell></fo:table-row><fo:table-row space-before.optimum="6pt"><fo:table-cell><fo:block font-style="italic" text-align="right">für den</fo:block></fo:table-cell><fo:table-cell><fo:block text-align="left">24.12.2000</fo:block></fo:table-cell></fo:table-row><fo:table-row space-before.optimum="6pt"><fo:table-cell><fo:block text-align="right"/></fo:table-cell><fo:table-cell><fo:block space-after.optimum="6pt" text-align="left">Nicht vergessen: <fo:inline-sequence font-weight="bold">Geschenke austeilen</fo:inline-sequence> </fo:block></fo:table-cell></fo:table-row><fo:table-row space-before.optimum="6pt"><fo:table-cell><fo:block text-align="right"/></fo:table-cell><fo:table-cell><fo:block space-after.optimum="6pt" text-align="left"> ... </fo:block></fo:table-cell></fo:table-row></fo:table-body></fo:table><fo:block space-before.optimum="30pt" text-align="justified"> Copyright © 2000 Stefan Mintert. Dieses Beispiel stammt aus der zweiten Auflage von »XML in der Praxis«. <fo:inline font-style="italic">http://www.mintert.com/xml/</fo:inline> </fo:block></fo:flow></fo:page-sequence></fo:root>
Abgesehen von der unleserlichen Formatierung ist doch zu erkennen, dass es sich um die gewünschte Ausgabe handelt. Zu beachten ist die Verarbeitungsanweisung cocoon-format type="text/xslfo", die die Formatierung veranlasst. Noch einmal sei betont, dass der Autor mit dieser Datei gar nicht in Berührung kommt. Wir haben hier wieder einen Blick hinter die Kulissen geworfen. Der Web-Surfer bekommt schließlich die formatierte Fassung als PDF-Datei übermittelt. Dessen Darstellung im Acrobat Reader zeigt Abbildung 72.