Transformationen
XML und XSLT
Hallo Welt!
Am Beispiel lernt es sich am besten. Daher stellen wir die wichtigsten XSLT-Befehle anhand dreier praktischer Beispiele vor, die Sie sich von [4] herunterladen oder auf der Heft-CD betrachten können.
Wie beim Lernen jeder (Programmier-)Sprache beginnen wir mit der klassischen "Hallo Welt!"-Anwendung, die nichts weiter tut, als den Text "Hallo Welt!" als HTML auszugeben. Die DTD dazu sieht so aus:
<!ELEMENT hallo (#PCDATA)>
Sie definiert ein einzelnes Element namens hallo – andere dürfen in der XML-Datei nicht auftauchen. Diese wiederum…
<?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE hallo SYSTEM "hallo.dtd">
… muss nicht nur die DTD einbinden, …
<?xml-stylesheet type="text/xsl" href="hallo.xsl" ?>
… sondern auch das Stylesheet. Das geht mit dem Attribut href des XSL-Befehls <?xml-stylesheet>. href legt auch den Pfad zur Stylesheet-Datei fest. Sie können hier absolute und relative Pfade angeben oder URLs verwenden. Das Attribut type bestimmt, welcher Art das Stylesheet ist, text/ssl zeigt dem Parser, dass es sich um ein XSL-Stylesheet handelt.
Zuletzt formatieren wir den Gruß Hallo Welt! als (in der DTD definiertes) hallo-Element:
<hallo>Hallo Welt!</hallo>
Listing 1
Stylesheet
hallo.xsl1 <?xml version="1.0" encoding="iso-8859-1"?> 2 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 3 <xsl:output method="html"/> 4 <xsl:template match="/"> 5 <html><head> 6 <title>Hallo</title> 7 </head> 8 <body bgcolor="ffffff"> 9 <p style="color:red"> 10 <xsl:value-of select="."/> 11 </p> 12 </body></html> 13 </xsl:template> 14 </xsl:stylesheet>
Das Stylesheet (Listing 1), das daraus eine HTML-Ausgabe machen soll, ist selbst ebenfalls eine XML-Datei und beginnt daher mit dem <?xml>-Tag. Der anschließend folgende Inhalt der Stylesheet-Definition wird von den XML-Tags <xsl:stylesheet> und </xsl:stylesheet> umschlossen. Mit dem version-Attribut dieses "Befehls" legen Sie in der zweiten Zeile die Version des Stylesheets fest, das als externe Datei eingebunden wird. Den Pfad zum Stylesheet geben Sie in der gleichen Weise ein wie den zur DTD in der XML-Datei.
In der dritten Zeile bestimmen Sie, in welches Format das Stylesheet die XML-Daten transformieren soll, hier ist es HTML. Nach der Angabe des Ausgabeformats folgt in Zeile 4 der Befehl <xsl:template match="/">. Das <xsl:template>-Tag enthält stets ein Attribut match, das festlegt, welches Element aus der XML-Datei transformiert werden soll. In der XPath-Schreibweise steht / für die Dokumentwurzel, die in diesem Fall dem <hallo>-Tag entspricht.
Nachdem Sie festgelegt haben, auf welches XML-Tag Sie sich beziehen, geben Sie an, welche HTML-Tags zur Formatierung verwendet werden sollen, ehe Sie das Schluss-Tag </xsl:template> setzen. Im Beispiel besteht das Template aus dem Code eines vollständigen HTML-Dokuments einschließlich Header (<head>-Tag) und Body. Der Körper der HTML-Datei soll einen einzelnen Abschnitt (<p> – "paragraph") enthalten, in dem der Inhalt des Tags <hallo> in roter Schrift ausgegeben wird. Um dies zu bewerkstelligen, verwenden wir den Befehl <xsl:value-of /> (Zeile 10). Sein Attribut select="." wählt den gesamten Inhalt des zu behandelnden Tags aus.
Jagt man die entsprechende XML-Datei samt DTD und Stylesheet durch den Parser, entsteht eine HTML-Datei, die folgenden HTML-Code enthält:
<html><head> <title>Hallo</title> </head> <body bgcolor="ffffff"> <p style color="red">Hallo Welt!</p>. </body> </html>
Dazu geben Sie in einer Konsole folgenden Befehl ein:
java com.icl.saxon.StyleSheet -o hallo.html hallo.xml hallo.xsl
Die oben gezeigte HTML-Ausgabe (die saxon-Option -o legt das Output-File fest) steht anschließend in der Datei hallo.html im Arbeitsverzeichnis – vorausgesetzt, Sie haben keine Fehlermeldungen bekommen. Abbildung 1 zeigt das Ergebnis der Umwandlung im Browser.
Adressbuch
Nach diesem einfachen Beispiel wagen wir uns an etwas Komplexeres: Die Adressdatenbank (Listing 2), die wir Ihnen in den letzten beiden Heften [1,2] vorgestellt haben, soll in einer Tabelle ausgegeben werden.
Listing 2
Die DTD zur Adressdatenbank
1 <!ELEMENT adressen (datensatz)> 2 <!ELEMENT datensatz (vorname,nachname,strasse,plz,ort,tel)+> 3 <!ELEMENT vorname (#PCDATA)> 4 <!ELEMENT nachname (#PCDATA)> 5 <!ELEMENT strasse (#PCDATA)> 6 <!ELEMENT plz (#PCDATA)> 7 <!ELEMENT ort (#PCDATA)> 8 <!ELEMENT tel (#PCDATA)>
Listing 3
Die Adressdaten
<?xml version = '1.0' encoding="iso-8859-1"?>
<adressen>
<datensatz>[…]
</datensatz>
<datensatz>
<nachname>Hansen</nachname>
<vorname>Karl</vorname>
<strasse>Fischergasse 12</strasse>
<plz>12345</plz>
<ort>Seeheim</ort>
<tel/>
</datensatz>[…]
</adressen>
Listing 4
Stylesheet für Adressdaten
1 <?xml version="1.0" encoding="iso-8859-1"?> 2 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 3 <xsl:output method="html"/> 4 <xsl:template match="/"> 5 <html><head> 6 <title>Telefonliste</title> 7 </head> 8 <body bgcolor="ffffff"> 9 <table> 10 <tr> 11 <th>Vorname</th> 12 <th>Nachname</th> 13 <th>Telefon</th> 14 </tr> 15 <xsl:for-each select="datensatz"> 16 <xsl:sort select="nachname"/> 17 <tr> 18 <td> 19 <xsl:value-of select="nachname"/> 20 </td> 21 <td> 22 <xsl:value-of select="vorname"/> 23 </td> 24 <td> 25 <xsl:value-of select="tel"/> 26 </td> 27 </tr> 28 </xsl:for-each> 29 </table> 30 </body></html> 31 </xsl:template> 32 </xsl:stylesheet>
In der DTD (Listing 2) definieren wir in Zeile 1 das Element adressen als Wurzel-Element. Davon leitet sich das Element datensatz ab. Jeder Datensatz enthält die Felder nachname, vorname, strasse, plz, ort und tel. Für die Ausgabe interessieren uns nur die Elemente nachname, vorname und tel.
Am Anfang des Stylesheets (Listing 4) wird wieder das Root-Element des XML-Dokuments aus Listing 3 ausgewählt (Zeile 4) und der Dateivorspann für die HTML-Ausgabe formatiert (Zeilen 5--8). Zusätzlich legen wir hier noch den Kopf einer HTML-Tabelle an (Zeilen 9--14).
Anschließend folgt die Formatierung der einzelnen Datensätze. Wir verwenden hier den XSL-Befehl <xsl:for-each> (Zeile 15), da wir in einer Schleife über die ganze XML-Datei gehen und alle Vorkommen des <datensatz>-Tags behandeln wollen. Mit dem Befehl <xsl:sort select="nachname"/> in Zeile 16 sortieren wir die Ausgabe aufsteigend nach Nachnamen. Sie können die Daten nach jedem beliebigen Feld auf- oder absteigend sortieren: Der Befehl
<xsl:sort select="vorname" order="descending"/>
würde sie in absteigender Reihenfolge nach Vornamen ordnen.
In der Schleife werden die drei Unterelemente von datensatz, nachname, vorname und tel, nacheinander ausgewählt und formatiert (Zeilen 17 bis 27). Jedes Datenfeld kommt in eine Tabellenzelle, die durch die HTML-Tags <td> für Table Data und </td> begrenzt wird. Das Tag </xsl:for-each> in Zeile 28 schließt die Schleife ab. Anschließend fügen wir den Dateifuß der HTML-Datei ein und beenden in den Zeilen 31 und 32 das Stylesheet.



