XSLT ist ein Bestandteil von XSL, der Stilsprache von XML, und für die Wandlung von XML-Dokumenten der einen Art in eine andere vorgesehen. Die Sprache lässt sich sowohl mit als auch ohne die Formatierungssprache XSL im engeren Sinne verwenden, denn eigentlich ist sie — im weiteren Sinne — deren Bestandteil. XSL im engeren Sinne ist hier die Sprache, die die Formatierung eines XML-Dokuments beschreibt — oft auch XSL-FO genannt (wegen der Formatier-Objekte).
Dass XSLT-Instanzen überhaupt Stylesheets genannt werden, hat zum einen historische Gründe; zum anderen haben sie tatsächlich diese Funktion, wenn sie das XML-Dokument mit den Formatierungsanweisungen versehen. Transformations-Stylesheets sind wohlgeformte XML-Dokumente, die der W3C-Empfehlung für Namensräume entsprechen müssen (siehe unten und das Kapitel 6). Sie bestehen aus einer Ansammlung von template-Regeln, die sich wiederum jeweils aus zwei Teilen zusammensetzen: einem Muster (pattern) und einer Schablone (template), die im Prozess der Transformation gleichsam aufgerufen wird. So entsteht je nach Art der Transformationen aus einem Quellbaum ein möglicherweise völlig anders gearteter Zielbaum.
Aus dem XML-Quellcode des obigen Absatzes
<absatz>Dass <acro>XSLT</acro>-Instanzen überhaupt <em>Stylesheets</em> genannt werden, hat zum einen historische Gründe; ...</absatz>
macht das folgende Bruchstück eines Stylesheet HTML:
<xsl:template match="absatz"> <p> <xsl:apply-templates/> </p> </xsl:template> <xsl:template match="acro"> <span class="acronym"> <xsl:value-of select="."/> </span> </xsl:template> <xsl:template match="em"> <em> <xsl:value-of select="."/> </em> </xsl:template>
wobei das erste Template einen Absatz (p)
erzeugt und das Ergebnis weiterer Templates in ihn
packt
, während die beiden anderen
ein Element span beziehungsweise ein
em mit dem jeweiligen Textinhalt generieren.
Dass XSLT-Dokumente wohlgeformtes XML beinhalten, dürfte der Hauptgrund dafür sein, dass diese Transformationssprache sich durchgesetzt hat. Wie gelegentlich in Andeutungen zu hören war, galt in einer frühen Phase der Diskussion um die Stilsprache (Formatierung und Transformation) das damals schon als Vorschlag vorliegende DSSSL-O von Jon Bosak als nicht mehrheitsfähig, vor allem weil es für Web-Autoren viel zu schwierig sei. Es handelte sich bei DSSSL-O um eine abgespeckte Version von DSSSL, der Transformations- und Formatierungssprache für SGML, eine Scheme-Implementierung.
Wie sich in diesem und in den praktischen Kapiteln zeigen wird, ist XSLT allerdings ebenso wenig geeignet, von Webautoren benutzt zu werden, die mit WYSIWYG-Autorenwerkzeugen zu arbeiten gewohnt sind. XSLT ist zwar nicht gerade Lisp, aber die Kontrolle über das, was das Stylesheet im Einzelnen macht, zu behalten, erfordert eine Art Programmiererblick (siehe zum Beispiel die Abfragen in Abschnitt 20.1).
Zwingender Bestandteil einer XSLT-Instanz ist stylesheet als Wurzelelement, das definiert, dass es sich bei diesem Dokument um XSLT handelt. Es muss mindestens das Attribut version und einen Verweis auf den Namensraum enthalten:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- Inhalt des Stylesheet: weitere Schablonen --> </xsl:stylesheet>
Statt der drei Buchstaben xsl
könnte man eine
beliebige Zeichenkette verwenden, um den
XSLT-Namensraum zu bezeichnen (der allerdings
muss heißen wie oben). Es ist allerdings zu befürchten, dass
XSLT-Implementierungen stillschweigend von xsl
ausgehen und Fehler ausgeben, wenn man den Namen tatsächlich
frei wählt.
Derzeit muss version den Wert 1.0 haben; und der Namensraum dieser Version von XSLT ist der in xmlns (XML-Namespace) angegebene. Das heißt, es dürfte weitere Versionen dieser Transformationssprache geben, und das W3C könnte sich auch entschließen, im Jahre 2001 eine neue Fassung der Version 1.0 herauszugeben. xsl:stylesheet kann weitere Namensraumfestlegungen enthalten. Und über diese beiden Attribute hinaus darf das Element auch eine Kennung (id) besitzen, sodass man ein Stylesheet auch aufrufen kann. Statt stylesheet kann alternativ transform stehen. Alle Elemente des XSLT-Namensraums müssen den dazugehörigen Bezeichner vorangestellt haben:
<xsl:import href="x.xsl"/>
Eine Ausnahme von der strikten Regel oben existiert allerdings: wenn das gesamte Stylesheet nur eine Schablone für den Wurzelknoten (/) enthält. Bezogen auf das in XML definierte HTML sähe ein solches verkürztes Stylesheet folgendermaßen aus:
<html version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/TR/xhtml1/strict"> <head> <title>mein Titel<title> <head> <body> <p><xsl:value-of select="//p/@id='id42"/><p> </body> </html>
Dadurch dass nicht unterschiedliche Templates existieren, die einander aufrufen, sondern das gesamte Stylesheet in HTML erzeugt wird, ist das Element stylesheet nicht erforderlich. Aus dem im Element html deklarierten Namensraum von XSLT kommt hier lediglich value-of zum Tragen. Obiges Stylesheet entspricht einem, das nur ein Template für / zum Inhalt hat und darin die HTML-Ausgaben wie oben erzeugt.
Für Stylesheets, die sich auf eine spätere, derzeit noch nicht existierende Version von XSLT beziehen, hat das W3C vorgesehen, dass Autoren durcheine Abfrage der Version Abwärtskompatibilität sicherstellen können. Ein Stylesheet, das mit xsl:stylesheet version="1.2" ... beginnt, kann beispielsweise über test="system-property('xsl:version') > 1.0" dafür sorgen, dass Eigenschaften der späteren Version nur in diesem Fall (Version > 1.0) zum Tragen kommen.
Abgesehen vom Wurzel-Element xsl:stylesheet sieht XSLT eine beliebige Anzahl weiterer Elemente vor. Einige davon sind explizit und nur direkt unterhalb von xsl:stylesheet erlaubt (so genannte Top-Level-Elemente). Hinter der beliebigen Anzahl stecken diejenigen, die in den Templates zu finden sind. Die Top-Level-Elemente sind der folgenden Tabelle zu entnehmen.
Element | Aufruf | Bedeutung |
---|---|---|
xsl:import | <xsl:import href=""datei.xsl"/> | Import eines Stylesheet; das importierende hat Vorrang (überschreibt im Falle von Überschneidungen) |
xsl:include | <xsl:include href="datei.xsl"/> | Kopiert ein Stylesheet in das aufrufende |
xsl:strip-space | <xsl:strip-space elements=" [Elementliste] "/> | Liste von Elementen, bei denen mehrere Leerraumzeichen zu einem verkürzt werden |
xsl:preserve-space | <xsl:preserve-space elements=" [Elementliste] "/> | Liste von Elementen, bei denen mehrere Leerraumzeichen erhalten bleiben |
xsl:output | <xsl:output method="xml" encoding="ISO-8859-1"/> | Legt unter anderem fest, ob die Ausgabe XML oder HTML sein soll, aber auch den Dokumenttyp und ob das Ergebnis eingerückt werden soll |
xsl:key | <xsl:key name="mykey" match="p" use="@name"/> | Erlaubt das Generieren von Cross-Referenzen; anders als ein Attribut vom Type id auf alle anwendbar |
xsl:decimal-format | <xsl:decimal-format name="deutsch" decimal-separator=","/> | Legt fest, wie das Trennzeichen für reelle Zahlen aussehen soll |
xsl:namespace-alias | <xsl:namespace-alias stylesheet-prefix="nonxsl" result-prefix="xsl"> | Alias für Stylesheets, die Styösheets erzeugen; erlaubt es beispielsweise, im XSLT-Stylesheet wie hier, nonxsl als zu benutzendes Präfix zu deklarieren, im Ergebnis aber xsl zu verwenden |
xsl:attribute-set | <xsl:attribute-set name="myname"> <!-- Setzen einzelner Attribute durch --> <xsl:attribute name="myname">myvalue</xsl:attribute> </xsl:attribute-set> | Erlaubt die Definition einer Menge von Attributen, die xsl:element über das Attribut use-attribute-sets nutzen kann; Inhalt ist eine Menge von xsl:attribute-Zuweisungen |
xsl:variable | <xsl:variable name="myname">myvalue</xsl:variable> | Deklaration einer Variablen myname, die den Wert myvalue hat |
xsl:param | <xsl:param name="thisparam"/> | Globale Deklaration eines Parameters, dessen Wert dem Stylesheet mit thisparam="meinparam" übergeben wird |
xsl:template | <xsl:template match="absatz">...</xsl:template> | Element, das eine durch das Muster absatz definierte Menge von Knoten bearbeitet |
<xsl:template name="myname">...</xsl:template> | Element, das über seinen Namen myname adressiert wird statt über ein Muster |
Für komplexe Stylesheets sind die beiden ersten besonders wichtig, denn sie ermöglichen es, Stylesheets aus mehreren zusammenzusetzen, das heißt beispielsweise, in einem Root-Template das Aussehen aller Ergebnisse (die Corporate Identity) vorzugeben. Von der anderen Seite betrachtet, dient import auch dazu, Allgemeines durch Konkretes zu überschreiben.
Dazu ein Beispiel: Generell dürfte ein Stylesheet für die Transformation von Gedichten (a) eine Schablone wie die folgende beinhalten:
<!-- Stylesheet-Fragment (a) --> <xsl:template match="line"> <xsl:apply-templates /><br /> </xsl:template>
Dies Template bewirkt die Ausgabe einer Zeile (line), gefolgt von einem Zeilenumbruch (<br />). Soll aber in einem konkreten Gedicht eine Zeile (oder mehrere) nicht nur ausgegeben werden, muss ein neues Stylesheet (b) her, das (a) importiert und nur das Template für die einzelne Zeile überschreibt:
<!-- Stylesheet-Fragment (b) --> <xsl:import href="poem.xsl"/> <xsl:template match="line"> <xsl:if test="position()=last()"> <img src="/images/transparent.gif" width="75" height="1" /> </xsl:if> <xsl:apply-templates/><br /> </xsl:template>
Fragment (b) importiert mit poem.xsl das
Stylesheet für normal
zu behandelnde Gedichte und
überschreibt nur, wie einzelne Zeilen behandelt werden
sollen. Durch die Abfrage der Position innerhalb einer
Strophe (position()=last()) ist hier erreicht,
dass vor der jeweils letzten Zeile mit Hilfe eines
transparenten Bildchens ein waagerechter Balken eingesetzt
wird, der die Zeile um 75 Pixel einrückt.
Wie das Gedichtbeispiel suggeriert, bedeutet ein Import von Stylesheets, dass das importierende eventuell in importierten vorhandene Templates überschreibt. Ein Inkludieren ersetzt das include-Statement schlicht durch den Inhalt des einzubindenden Stylesheets. Für beide Elemente gilt, dass kein Stylesheet sich selbst einbinden darf. Und beim Import von Stylesheet ist zu beachten, dass nicht nur das importierende Stylesheet Vorrang hat, sondern auch eine explizite Ordnung zwischen den Importierten definiert ist.
Importiert ein Stylesheet mehrere andere, die wiederum weitere importieren, gilt zweierlei:
Um es mit dem Beispiel aus der Spezifikation zu sagen: wenn A die Stylesheets B und C importiert (gleiche Hierarchiestufe), B das Stylesheet D importiert und C wiederum E, dann lautet die Vorrangfolge der Stylesheets: A, C, E, B, D.
Dankenswerterweise kann man den Vorrang auch selbst steuern: durch das Element apply-imports. Es bewirkt, dass ein Template mit niederem Import-Vorrang zum Einsatz kommen kann.