XML gut und schön – doch ohne formatierte Darstellung ist es nur die Hälfte wert. Der dritte Teil unserer Miniserie beschäftigt sich mit der Ausgabe von XML-Daten mit Hilfe von XSLT.
Wohlgeformte XML-Dokumente zu erstellen, ist keine Kunst – ob mit einem gängigen Texteditor oder einem speziellen XML-Editor [1]. Eine DTD dazu [2] – schon wird daraus ein gültiges Dokument. Doch noch steht nicht fest, wie ein solches zur Anzeige formatiert wird. Hier kommen Stylesheets ins Spiel und damit die Sprache XSL (“EXtensible Stylesheet Language”).
Diese “erweiterbare Formatsprache” besteht aus zwei Teilen: einer Komponenten zur Formatierung von XML-Daten und einer zweiten zur Transformation der XML-Daten in andere Formate. In diesem Artikel behandeln wir die Extensible Stylesheet Transformation, also die Umwandlung von XML-Daten in andere Formate. XSLT schreibt dabei den XML-Baum in einen anderen Baum um, etwa XHTML. Dabei können Sie alle Möglichkeiten zur Darstellung Ihrer Daten benutzen, die HTML bietet, einschließlich JavaScript und CSS.
Bäume und Wege
Um ein XML-Dokument zu transformieren, muss man auf jedes Element des XML-Baumes zugreifen können. Aus diesem Grund wurde XPath entwickelt. Diese Sprache verfügt über Befehle, Operatoren und Symbole, mit denen Sie jeden “Zweig” der XML-Datei erreichen, aber auch manipulieren und auswerten können.
Beim Verständnis der “XML Path Language” hilft das Wissen um die Organisation des Linux-Dateibaums. Dieser beginnt mit dem Root-Directory, von dem sich, einer Wurzel gleich, alle Verzeichnisse ableiten. Sie können jedes Element innerhalb des Dateisystems über einen Pfad ansprechen, der von diesem, mit einem Schrägstrich gekennzeichneten Ursprung ausgeht. Genauso verhält es sich in einem XML-Dokument. Auch hier gibt es ein Wurzel-(root-)Element, von dem sich alle Elemente des Dokuments ableiten.
Beim Adressieren der Elemente einer XML-Datei kommt die gleiche Syntax wie im Unix-Dateibaum zum Einsatz. Das Root-Element heißt in XPath /. Um etwa das Element vorname aus folgendem Ausschnitt einer XML-Datei anzusprechen, …
<adressen> <datensatz> <vorname>
… dient der Pfad /adressen/datensatz/vorname.
Werkzeuge
Ein XSL-Stylesheet enthält Anweisungen, um ein XML-Dokument in ein anderes Format umzuwandeln. Darin notieren Sie, was der XSLT-Parser mit den XML-Tags anstellen soll.
Um ein Stylesheet zu schreiben, benötigen Sie nichts weiter als einen beliebigen Editor, der Texte unformatiert speichert. Um eine XML/XSLT-Seite darzustellen, brauchen Sie einen Browser, der XSLT kann, oder einen XSLT-Parser. Saxon ist ein solcher. Da er in Java geschrieben wurde, funktioniert er auf allen Betriebssystemen, auf denen eine Java Virtual Machine installiert ist.
Die Erstausstattung eines angehenden XML-Autors könnte etwa so aussehen: der Editor Kate zum Kodieren der Stylesheets, KXMLEditor zum Schreiben der XML-Dateien, Saxon zum Erzeugen der HTML-Dateien und Konqueror sowie Mozilla zum Betrachten des Ergebnisses.
Saxon bekommen Sie auf der Programm-Homepage [3]. Sie laden die Datei saxon.zip herunter und entpacken sie in einem beliebigen Verzeichnis mit dem Befehl
unzip saxon.zip
Anschließend kopieren Sie die Datei saxon.jar in ein Verzeichnis, das im CLASSPATH steht.
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.xsl
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>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.
Großprojekt Zeitschrift
Als drittes Beispiel wagen wir uns an eine stark vereinfachte Anwendung für die Realisierung einer Zeitschrift in XML; die DTD finden Sie in Listing 5.
Hier gibt es einige Besonderheiten zu beachten: Das Element absatz (Zeile 10) kann sowohl Text vom Typ #PCDATA sein als auch die Elemente listing und begriff enthalten, damit der Autor eines Artikels in einem Absatz auch Listings und Glossareinträge markieren kann.
Alle anderen Elemente werden wie gewohnt definiert, das Wurzel-Element heißt zeitschrift.
Listing 5
Zeitschriften-DTD
1 <!ELEMENT zeitschrift (artikel)*> 2 <!ELEMENT artikel (rubrik,titel,autor,vorspann,text)*> 3 <!ELEMENT rubrik (#PCDATA)> 4 <!ELEMENT titel (#PCDATA)> 5 <!ELEMENT autor (#PCDATA)> 6 <!ELEMENT vorspann (#PCDATA)> 7 <!ELEMENT text (zwischenueberschrift | erklaerung | absatz )> 8 <!ELEMENT zwischenueberschrift (#PCDATA)*> 9 <!ELEMENT erklaerung (#PCDATA)> 10 <!ELEMENT absatz (#PCDATA | listing | begriff)*> 11 <!ELEMENT listing (#PCDATA)> 12 <!ELEMENT begriff (#PCDATA)>
Eine XML-Datei für eine – zugegeben sehr rudimentäre – Zeitschrift, die aus genau einem Artikel besteht, finden Sie in Listing 6. In Zeile 14 sehen Sie, wie das listing-Element innerhalb eines <absatz /> verwendet wird.
Listing 6
Rudimentäre Zeitschrift
1 <?xml version = '1.0' encoding="iso-8859-1" ?> 2 <!DOCTYPE zeitschrift SYSTEM "zeitschrift.dtd"> 2 <?xml-stylesheet type="text/xsl" href="zeitschrift.xsl" ?> 3 <zeitschrift> 4 <artikel> 5 <rubrik>Programmierung</rubrik> 6 <titel>BASIC für Anfänger</titel> 7 <autor>Kalle Schlaumeier</autor> 8 <vorspann>BASIC ist wieder groß in Mode.</vorspann> 9 10 <absatz> 11 BASIC ist schon uralt. Bereits in der PC-Steinzeit haben 12 Programmierer in dieser Sprache Programme geschrieben. Das 13 berühmte Hallo-Welt-Beispiel sieht in BASIC so aus: 14 <listing>15 print "Hallo, Welt!"</listing> 15 </absatz> 16 <zwischenueberschrift>Geschichte</zwischenueberschrift> 17 <absatz> 18 Selbst in der Zeit von modernen <begriff>GUI</begriff>- 19 Toolkits hat eine Sprache wie BASIC durchaus noch ihre Daseinsberechtigung. 20 </absatz> 21 <erklaerung> GUI: Graphical User Interface - Grafische Benutzerschnittstelle. 22 </erklaerung> 23 24 </artikel> 25 </zeitschrift>
Das Listing eines Stylesheets für die Online-Ausgabe unserer imaginären Zeitschrift ist zu umfangreich, um es hier abdrucken zu können. Sie finden es daher auf der Heft-CD.Die Formatierung des Root-Elements erfolgt wie inzwischen gewohnt. Um die Verschachtelung der Tags umzusetzen, verwenden wir den XSL-Befehl <xsl:apply-templates />:
<xsl:template match="/">
<html><head><title>Zeitschrift</title>
</head><body bgcolor="ffffff">
<xsl:apply-templates />
</body></html>
</xsl:template>
Mit diesem Befehl weisen Sie den Parser an, Vorlagen zu verwenden, die außerhalb dieser <apply-templates />-Anweisung stehen. Der Parser durchsucht daraufhin das Stylesheet nach einer passenden template-Definition und verwendet die passende Vorlage.
Für das Element rubrik etwa findet sich folgende Definition:
<xsl:template match="rubrik"> <h4><xsl:value-of select="." /></h4> </xsl:template>
Immer, wenn der Parser innerhalb der XML-Datei auf ein Element dieses Namens trifft, wird er es entsprechend dieser Definition umwandeln.
Bei einteiligen HTML-Tags innerhalb von XSL, wie z. B. <hr> zum Einfügen einer Linie oder <img> zum Einbinden von Grafiken, gilt es für HTML-Gewöhnte, sich etwas umzustellen:
<xsl:template match="erklaerung"> <p> <hr />[…] </p> </xsl:template>
Derartige Tags müssen – anders als in alten HTML-Versionen – stets von einem Ende-Tag abgeschlossen werden, da es in XML keine “offenen” Tags geben darf. Selbstverständlich ist dabei auch die XML-Kurzschreibweise für leere Tags (also <hr /> oder <img />) erlaubt.
Wozu das Ganze?
Auf diese Mühsal folgt die Ernüchterung: All diese Beispiele ließen sich mit weniger Aufwand direkt in HTML realisieren. Warum also die Umstände? Mit XML/XSLT trennen Sie Daten und Formatierung so mühelos wie vollständig. Statt in einer komplexen, mit Formatierungsinformationen überfüllten einfachen HTML-Datei herumzustochern, um deren Aussehen im Browser zu ändern, passen Sie lediglich das Stylesheet an und lassen die Daten in Ruhe. Zudem ist es mit XSLT möglich, aus einer Datenquelle verschiedene Ausgabeformate – nicht nur HTML – zu erzeugen.
Diesen Vorteil nutzt etwa das KDE-Projekt. Statt für die Programmdokumentation PDF– und HTML-Versionen getrennt zu pflegen, wird die in einem XML-Format geschrieben: DocBook. Die Konvertierung dieser Texte nach HTML oder PDF übernimmt der Prozessor Jade, der, anders als Saxon, neben der Transformation von XML in HTML auch noch andere Formate erzeugen kann, aber dafür wesentlich schwieriger zu bedienen ist.
Eine Anleitung zum Schreiben von Dokumentation für KDE finden Sie unter [5], während [6] beschreibt, welche Programme Sie zum Transformieren der XML-Daten in Dokumente für die KDE-Online-Hilfe benötigen.
Um aus einer DocBook-Datei eine Sammlung von HTML-Dateien zu machen, steht Ihnen das Programm docbook2html zur Verfügung, das im Paket kdelibs enthalten ist. Der Befehl
docbook2html \ -c /usr/share/apps/ksgmltools/catalog \ -d /usr/share/apps/ksgmltools/stylesheets/kde.dsl#html \IhreDatei.docbook
ruft das Konvertierungsprogramm auf, das aus der XML-Datei IhreDatei.docbook eine Reihe von HTML-Dateien erzeugt. Der Parameter -c verweist auf das Verzeichnis, das die DTD enthält, -d sagt dem Parser, in welchem Verzeichnis die Stylesheets zu finden sind.
Unter [7] und [8] finden Sie übrigens eine ausführliche Einführung in XSLT, die auch Aspekte wie Links und Einbindung von Grafiken bespricht. Ausführliche Informationen über XPath liefert [9] – genügend Stoff, der Sie bei Ihrer nunmehr bereits fortgeschrittenen Beschäftigung mit XML begleiten kann.
Glossar
-
XML
-
“EXtensible Markup Language”. Eine auf SGML basierende Auszeichnungssprache, mit der Möglichkeit, eigene Tags zu definieren.
-
DTD
-
“Document Type Definition”. In einer DTD werden XML-Tags und ihre Eigenschaften definiert.
-
XHTML
-
Die neueste, auf XML basierende Version der “HyperText Markup Language”, der Seitenbeschreibungssprache des World Wide Webs.
-
JavaScript
-
Eine in HTML eingebettete Skriptsprache, mit der interaktive Elemente innerhalb von Web-Seiten realisiert werden können.
-
CSS
-
“Cascading Style Sheets” ermöglichen die Formatierung von HTML-Elementen.
-
Pfad
-
Der “Weg” zu einer Datei auf einem lokalen Dateisystem, also die Angabe aller Verzeichnisse, über die man “gehen” muss, um zu ihr zu gelangen.
-
Parser
-
Ein XSL-Parser ist ein Programm, das XSL-Dateien einlesen und auf Richtigkeit überprüfen kann.
-
Java Virtual Machine
-
Ein Programm, das vorkompilierte Java-Programme ausführen kann. Neben der JVM aus dem “Java Runtime Environment” (JRE) der Firma Sun gibt es als freie Alternativen Kaffe und Blackdown.
-
CLASSPATH
-
Diese Variable, der Java-Classpath, enthält die Verzeichnisse, in denen Java-Klassen, Programme und Bibliotheken abgelegt werden.
-
URL
-
“Uniform Resource Locator”, die eindeutige Adressenangabe für eine Datei im Internet.
-
PDF
-
“Portable Document Format”. Ein von der Firma Adobe entwickeltes Dateiformat zur Weitergabe formatierten Textes.
Infos
[1] Frank Wieduwilt: “Schachtelhelfer”, LinuxUser 11/2001, S. 44 ff.
[2] Frank Wieduwilt: “Typenfrage”, LinuxUser 12/2001, S. 94 f., http://www.linux-user.de/ausgabe/2001/12/094-xml/dtd-5.html
[3] http://users.iclway.co.uk/mhkay/saxon/
[4] http://www.wieduwilt.org/xml/xslt-artikel.zip
[6] http://i18n.kde.org/teams/de/
[7] http://selfhtml.teamone.de/xml/darstellung/xslgrundlagen.htm
[8] http://www.melonfire.com/community/columns/trog/article.php3?id=82
[9] http://www.melonfire.com/community/columns/trog/article.php3?id=83







