Kontakt aufnehmen

Programmieren mit XSLT

XSLT bietet neben dem simplen Einfügen von Code in bestimmte Vorlagen (templates) die Möglichkeit quasi Programmabläufe zu definieren. Somit kann das Resultat dynamischer und atraktiver generiert werden.

Kopieren

Um Elemente des Quellbaums in das Resultat zu übernehmen kopiert man sie mit Hilfe des xsl:copy-Elements. Es kann innerhalb von Templates verwendet werden und veranlasst, dass der aktuelle Knoten, d.h. also das aktuelle Element, in das Resultat kopiert wird. Ein eventueller Namespace wird dabei übernommen - jedoch keine Attribute oder Unterelemente. Außerdem steht wiederum das bereits bekannte use-attribute-sets-Attribut zur Verfügung. Beispiel:

<xsl:template match="B"> a <xsl:copy> b </xsl:copy> c </xsl:template>

... erzeugt:

a <B> b </B> c

Bitte beachten Sie, dass dieses Element nur auf Element-Knoten angewandt werden darf.

außerdem besteht eine zweite Möglichkeit des Kopierens: xsl:copy-of. Dieses Element kopiert - im Gegensatz zu xsl:copy - den gesamten mit select definierten Knoten, inklusive Unterknoten aus dem Quell-Dokument in das Resultat-Dokument.

Nummerierungen erzeugen

Nummerierungen können z.B. bei Überschriften, Kapitel-Bezeichnungen oder einfach Listen zur Anwendung kommen. Man definiert sie mit dem xsl:number-Element. Es hat folgende Attribute:

  • level - Beschreibt, ob die Aufzählung nur auf einer (single/Standard), mehreren (multiple) oder allen (any) Zweigen des Quell-Baumes fortgeführt werden soll.
  • count - Beschreibt einen Patter (siehe oben), bei dessen Auftreten der Zählwert erhöht werden soll. Standard ist der Pattern des Templates.
  • from - Beschreibt einen Patter, bei dessen Auftreten der Zähler zu zählen anfangen soll (~zurücksetzten). Als Standard gilt jedes Elternelement.
  • value - Funktion oder XPath-Ausdruck der die Berechnung des Zählerstandes erlaubt. Standard ist position().
  • format - String der das Format der Ausgabe beschreibt (1, a, A, i, I). Alle anderen Zeichen werden als Zusatz angesehen.
  • lang - Beschreibt eine Sprache aus dessen Alphabet die Zeichen verendet werden sollen.
  • letter-value - Beschreibt, ob alphabetische (alphabetic) oder traditionelle (traditional/Standard) Zählweise verwendet werden soll.
  • grouping-separator - Trennzeichen für Gruppierungen (wie z.B. bei 1.000.000).
  • grouping-size - Zahl die die Größe der Gruppierungen beschreibt.
Beispiel:

<xsl:template match="H4"> <xsl:number level="any" from="H1" count="H2"/> <xsl:text>.</xsl:text> <xsl:number level="any" from="H2" count="H3"/> <xsl:text>.</xsl:text> <xsl:number level="any" from="H3" count="H4"/> <xsl:text> </xsl:text> <xsl:apply-templates/> </xsl:template>

Wiederholungen

Unter Umständen ist es notwendig bestimmte Abläufe oder Knoten innerhalb eines Templates in einer gewissen Reihenfolge durchlaufen zu lassen. Dazu verwendet man das xsl:for-each-Element. Es erhält als Wert des select-Attributes einen Patter. Wird das xsl:for-each-Element aufgerufen, so wird der enthaltene Inhalt so oft in das Resultat geschrieben, wie der Patter in dem für das Template definierte Element auftritt. Beispiel Quelle:

<?xml version="1.0" ?> <?xml-stylesheet href="test1.xsl" type="text/xsl" ?> <!DOCTYPE A [ <!ELEMENT A ( B )*> <!ELEMENT B ( C | B )*> <!ELEMENT C EMPTY> ]> <A> <B><C /><C /><C /></B> <B><C /><C /><C /><C /></B> </A>

StyleSheet:

<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <table> <xsl:for-each select="A/B"> <tr> <th><xsl:apply-templates select="."/></th> <xsl:for-each select="C"> <td><xsl:apply-templates select="."/></td> </xsl:for-each> </tr> </xsl:for-each> </table> </xsl:template> <xsl:template match="B">TH</xsl:template> <xsl:template match="C">TD</xsl:template> </xsl:stylesheet>

... ergibt:

Resultat der Transformierung Darstellung: Resultat der Transformierung

Bedingte Abschnitte

Innerhalb von XSLT gibt es die Möglichkeit Transformationen nur dann auszuführen, wenn eine bestimte Bedingung erfüllt ist. Dazu wird das xsl:if-Element verwendet. Die Bedingung wird als Wert des test-Attributes notiert und ergibt dieser true (also Wahr) wird der Inhalt des Elements in das Resultat-Dokument übernommen - ansonsten nicht. Beispiel:

<xsl:template match="A"> <xsl:if test="position() mod 2 = 0"> <p>1</p> </xsl:if> <xsl:if test="position() mod 2 = 1"> <p>2</p> </xsl:if> </xsl:template>

... ergibt: 12121212 ...

Auswahl treffen

Wenn die Auswahl durch xsl:if nicht mehr ausreicht bzw. zu umständlich wird, kann dieses Element durch (drei) andere Elemente ersetzt werden: xsl:choose, xsl:when und xsl:otherwise. Ähnlich wie in anderen Programmiersprachen wird so eine Mehrfachauswahl definiert. Die gesamte Auswahl wird von xsl:choose umschlossen. Darin enthalten sind xsl:when und xsl:otherwise. Das xsl:when-Element beschreibt mit Hilfe des test-Attributes eine Bedinung. Ist diese erfüllt, wird der Inhalt des Elementes in den Resultat-Baum übernommen - die anderen Bedinungen werden dann nicht weiter betrachtet und der Parser schreitet mit dem nächsten Knoten nach dem schließenden xsl:choose-Tag fort. Ist die Bedinungung nicht erfüllt, schreitet der Parser zum nächsten xsl:when weiter und prüft diese. Wurde auch die letzte Bedinungen nicht erfüllt, wird letztlich der Inhalt des xsl:otherwise-Elements übernommen. Beispiel:

<xsl:template match="C"> <xsl:choose> <xsl:when test="position() mod 3 = 0"><p>0</p></xsl:when> <xsl:when test="position() mod 3 = 1"><p>1</p></xsl:when> <xsl:otherwise><p>2</p></xsl:otherwise> </xsl:choose> </xsl:template>

... ergibt: 120120120120 ...

Sortieren

Die Reihenfolge von Daten ist z.B. besonders bei langen unübersichtlichen Listen sehr wichtig. Das Sortieren der Daten kann mit XSLT bestimmt und beeinflusst werden. Wird das Element xsl:sort definiert, so besagt es, dass die einzufügenden Inhalte vorher zu sortiern sind. Durch die Attribute select, data-type, lang, order und case-order kann die Sortierung näher bestimmt werden:

  • select - enthält einen Patter (Standard ist .) der beschreibt, welche Knoten sortiert werden sollen.
  • lang - enthält eine Sprachdefinition (de, en, ...) die zur Sortierung verwendet werden soll.
  • data-type - beschreibt, ob die zu sortierenden Knoten wie Strings (text/Standard), Zahlen (number) oder andere Datentypen (Angabe des Datentypes nach XML-Names) sortiert werden sollen.
  • order - beschreibt, ob die Daten aufsteigend (ascending/Standard) oder absteigend (descending) sortiert werden soll.
  • case-order - beschreibt, ob bei data-type="text" die kleinen (upper-first) oder die großen Buchstaben (lower-first) als erstes einsortiert werden sollen. (Also ob a,b,c,A,B,C oder A,B,C,a,b,c)
Als Beispiel, wollen wir unser Adressbuch aus dem ersten Kapitel sortiert nach Namen ausgeben lassen. Wir fügen dem Buch allerdings noch einige Personen hinzu:

<?xml version="1.0" ?> <?xml-stylesheet href="trans.xsl" type="text/xsl"?> <Adressbuch> <Kunde Name="Max Mustermann"> <Adresse> <Strasse>Musterstrasse 14</Strasse> <PLZ>12345</PLZ><Ort>Mustehausen</Ort> </Adresse> </Kunde> <Kunde Name="August Ausgedacht"> <Adresse> <Strasse>Gibts-Nicht-Weg 37</Strasse> <PLZ>67890</PLZ><Ort>Augsburg</Ort> </Adresse> </Kunde> <Kunde Name="Gunter Gibtsnicht"> <Adresse> <Strasse>Hauptstrasse 001</Strasse> <PLZ>65381</PLZ><Ort>Berlin</Ort> </Adresse> </Kunde> <Kunde Name="Jutta Jefferson"> <Adresse> <Strasse>Bahnhofsweg 123</Strasse> <PLZ>86413</PLZ><Ort>Hamburg</Ort> </Adresse> </Kunde> </Adressbuch>

StyleSheet:

<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <h1>Kunden</h1> <table> <tr><th>Kunde</th><td>Strasse</td><td>PLZ Ort</td></tr> <xsl:for-each select="Adressbuch/Kunde"> <xsl:sort select="@Name"/> <tr> <th><xsl:value-of select="@Name"/></th> <td><xsl:value-of select="Adresse/Strasse" /></td> <td> <xsl:value-of select="Adresse/PLZ" /> <xsl:text> </xsl:text> <xsl:value-of select="Adresse/Ort "/> </td> </tr> </xsl:for-each> </table> </xsl:template> </xsl:stylesheet>

... erzeugt:

Resultat der Transformierung Darstellung: Resultat der Transformierung

Bitte beachten Sie, das dieses Element nur innerhalb von xsl:apply-templates oder xsl:for-each auftreten darf.

Variablen und Parameter

Wenn innerhalb des gesamten Dokumentes ein bestimmter Text immer wieder auftritt, oder es Schwierigkeiten mit dem Erstellen von Attributen gibt (weil acb="def=""" einen Fehler ergibt), können Variablen zum Einsatz kommen. Diese definiert man mit Hilfe des xsl:variable- oder xsl:param-Elements. Beide funktionieren in etwa gleich: Als Wert des name-Attributes wird der Variablenname definierte und innerhalb des Elements der Wert. Dieser kann aus fast allen beliebigen Dingen bestehen (Text, Markup, ...). Einziger Unterschied der beiden ist, dass der Wert von xsl:param als Standardwert gilt; wenn das Template oder StyleSheet in dem das xsl:param-Element auftritt aufgerufen wird, können die Parameter (xsl:param) als Standardwerte verwendet werden (siehe unten). Um die Werte nun wiederum abzurufen, wird das xsl:value-of (bzw. { und }) benutzt und diesem ein Dollar-Zeichen ($) sowie der Variablenname übergeben. Beispiel:

<xsl:variable name="wert">@Name="Max Mustermann"</xsl:variable> <xsl:value-of select="Adressbuch/Kunde[$wert]"/>

... gibt den Inhalt des Kunden mit dem Namen "Max Mustermann" aus.

Bitte beachten Sie die Lebensdauer von Variablen: Eine Variable besteht nur innerhalb eines Templates oder StyleSheets. Wird innerhalb eines untergeordneten Templates ein neuer Wert für die Variable definiert, so überschreibt dies nicht die eigentliche Variable. Ist der Bereich des neuen Wertes zu Ende, tritt der vorherige wieder in Kraft. Um Parameter innerhalb eines Templates verwenden zu können, müssen diese an das jeweilige Template übergeben werden. Dies geschieht mittels des xsl:with-param-Elements, welches als Attribut den Namen des Parameters erhält. Wird es aufgerufen, so übergibt es den Wert des Parameters an den gleichnamign Parameter. Beispiel:

<xsl:template name="bekomm-parameter"> <xsl:param name="meinparameter">Standardwert</xsl:param>

Der Wert des Parameters ist: <xsl:value-of select="$format"/> </xsl:template> <xsl:template match="sende-parameter"> <xsl:call-template name="bekomm-parameter"> <xsl:with-param name="meinparameter">Neuer Wert</xsl:with-param> </xsl:call-template> </xsl:template>

Behandlung von Whitespaces

Neben der normalen Behandlung von Whitspaces durch XML , kann diese für den XSLT-Parser nochmals konkret festgeschrieben werden. Dies kann durch zwei Elemente geschehen: xsl:strip-space und xsl:preserve-space. Beide Elemente erhalten dazu ein elements-Attribut, welches als Wert eine durch Leerzeichen getrennte Liste von Elementnamen enthält. Bei allen Elementen, die so mit dem xsl:strip-space-Element ausgezeichnet werden, werden die Whitespaces zusammen gefasst (wie in XML beschrieben). Bei allen Elementen, die durch xsl:preserve-space definiert werden, bleiben die Whitespaces erhalten. Grundsätzlich brauchen Elemente nicht extra mit xsl:strip-space definiert werden - sollen jedoch bei Elementen, die sich innerhalb eines mit xsl:preserve-space beschriebenen Elements befinden, die Whitespaces gekürzt werden, sollte dies hier definiert werden. Beispiel:

<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- import/include --> <xsl:strip-space elements="Adressbuch Strasse"> <xsl:preserve-space elements="Person"> <!-- sonstiges --> </xsl:stylesheet>

Bitte beachten Sie, dass beide Top-Level Elemente sind und möglichst vor Templates definiert werden sollten. Außerdem kann, anstelle einer Liste, der Joker (*) definiert werden. Er besagt, dass alle Elemente gemeint sind.

Darüber hinaus besteht eine dritte Möglichkeit um Text unbedingt so übernehmen zu lassen, wie er notiert wurde: Alles was innerhalb eines xsl:text-Elements notiert wird, wird ebenso auch in das resultierende Dokument übernommen (inklusive aller Whitespaces). Beispiel:

<xsl:text> Dieser Text wird genau so auch im Resultat erscheinen! </xsl:text>

XSLT-Software

Neben dem Mozilla Browser gibt es einige - meist serverseitige - Tools, die es erlauben XML Dateien zu transformieren. Dazu gehören unter anderem Cocoon, Xalan oder Sun's JAXP:

  • http://www.mozilla.org - Mozilla (Browser)
  • http://xml.apache.org/cocoon/index.html - Cocoon ( XSLT Server Plugin)
  • http://xml.apache.org/xalan-j/index.html - Xalan ( Java XSLT Parser)
  • http://java.sun.com/xml/jaxp/index.html - JAXP ( Java TM API for XML Processing)

Du arbeitest in einer Agentur oder als Freelancer?
Dann wirf doch mal einen Blick auf unsere Software FeatValue.

Weiterlesen: ⯈ Website-Inhalt und Design komplett trennen mit XSLT

Über uns

Stefan Wienströer

Wir entwickeln Webanwendungen mit viel Leidenschaft. Unser Wissen geben wir dabei gerne weiter. Mehr über a coding project

Cookie-Einstellungen

Helfen Sie dabei, uns noch besser zu machen. Wir nutzen Cookies und ähnliche Technologien, um die Website auf Ihre Bedürfnisse anzupassen. Zur Datenschutzerklärung

Auswahl speichern