XSLT-Stylesheet

Aus Wikibati
Version vom 6. September 2016, 14:53 Uhr von N.raebiger (Diskussion | Beiträge)

(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Wechseln zu: Navigation, Suche

In diesem Abschnitt beschreibe ich die wichtigsten Befehle in einem XSLT-Stylesheet. Um sich selbst ein Stylesheet zu erstellen, ist es sinnvoll, die Struktur der XML-Datei aus Kiribati zu verstehen.

Grundgerüst des Stylesheets

Eingeleitet wird ein XSLT-Stylesheet durch

Version 1.0

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

  <xsl:output method="xml" version="1.0" encoding="UTF-8" standalone="yes" indent="yes"/>

Version 2.0

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:fn="http://www.w3.org/2005/xpath-functions"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  version="2.0">

  <xsl:output method="xml" version="1.0" encoding="UTF-8" standalone="yes" indent="yes"/>

Der Unterschied besteht in der Versionsmitteilung 1.0 oder 2.0 und den aufgeführten Namensräumen (Namespaces xmlns:fn und xmlns:xs - diese werden von der Version 1.0 nicht zur Verfügung gestellt).

Die xsl:output Anweisung weist den Compiler an, eine neue XML-Datei zu erstellen.

Als nächstes wird in beiden Versionen das Template erstellt. Dies geschieht durch:

    <xsl:template match="/">
        ...
    </xsl:template>

Der Matchparameter gibt an, auf welches Element das Template bezogen wird match="/" gibt an, dass das Template für die gesamte Datei gilt.

Abgeschlossen wird das Stylesheet noch durch das schließende Tag

</xsl:stylesheet>

XSLT-Befehle

Eine XML-Datei zeichnet sich durch einen strukturierten Inhalt aus. Die Struktur wird mit sogenannten Tags dargestellt. XML selbst steht für Extensible Markup-Language, also eine erweiterbare Beschreibung der Struktur. Ein Tag besteht aus einem öffnenden und einem schließenden Element: <element>INHALT</element>. Ist der Inhalt leer, wird das öffnende Tag als <element /> geschrieben. element ist ein freiwählbarer Text aus Buchstaben, Ziffern und dem Unterstrich.

Auch ein XSLT-Stylesheet wird durch Tags beschrieben, die wie in einer XML-Datei aufgebaut sind. Den einzelnen Befehlen wird allerdings ein Namensraum vorangestellt: xsl:. Die hier beschriebenen Tags sind eine Auswahl, die für die Verarbeitung einer XML-Datei aus Kiribati zur Vorbereitung des Imports in InDesign hilfreich sein können. Weitere Tags und detailierte Beschreibungen können leicht über eine Suchmaschine gefunden werden (z. B. [1]). Die Anweisungen zur Verarbeitung der XML-Datei werden zwischen <xsl:template match="/">...</xsl:template> geschrieben.


Element erstellen

Möchte man ein neues Feld erstellen, teilt man dies dem Stylesheet durch das Tag <xsl:element name="Bezeichnung"> mit. Zwischen das öffnende und das schließende Tag wird dann der Inhalt gestellt. Der Inhalt kann entweder ein statischer Text sein, oder durch das Stylesheet berechnet werden.

<xsl:element name="Bezeichnung">Statischer Text</xsl:element>


<xsl:element name="veranstaltungen">...</xsl:element>
Damit wird ein umschließenden Tag um alle aufgeführten Veranstaltungen erstellt. Gleiches ist in der Ausgangsdatei zu finden. Dieses Tag wird als Root-Tag bezeichnet. In InDesign wird dieses Element dann in das Textfeld gezogen.


Mehrere gleiche Elemente behandeln

In der Ausgangsdatei sind die Daten der einzelnen Veranstaltungen jeweils zwischen <veranstaltung>...</veranstaltung> enthalten. Die einzelnen Veranstaltungen müssen nun auch einzeln behandelt werden. In einem XSLT-Stylesheet wird dies in einer fore-each-Schleife erledigt (für alle Elemente eines Pfades - in unserem Fall veranstaltungen/veranstaltung).

<xsl:fore-each select="Pfad">...</xsl:fore-each>


<xsl:fore-each select"veranstaltungen/veranstaltung">...</xsl:fore-each>
Durch diese Anweisung wird die Schleife so oft durchlaufen, bis alle Veranstaltungen in der XML-Datei bearbeitet wurden.

Anmerkung: Innerhalb der Schleife muss dann noch ein <xsl:element name="veranstaltung">...</xsl:element> aufgenommen werden, damit in der Ausgabedatei jede Veranstaltung auch wieder in einem eigenen Pfad enthalten ist.


Element aus der Ausgangsdatei kopieren

Möchte man ein Element komplett übernehmen, kann man dies ganz einfach durch die Anweisung <xsl:copy-of select="Bezeichnung" /> erledigen. Damit wird das Element inklusive der umschließenden Tags in die Ausgabedatei kopiert.


<xsl:copy-of select="ver_titel1" />
Kopiert das Feld ver_titel1 in die Ausgabedatei.


Nur den Wert eines Elements übernehmen

Im Gegensatz zu copy-of kann man mit value-of auf den Wert eines Elements zugreifen. Dadurch kann man z. B. mehrere Elemente zusammenfassen, den Wert in einer Variablen zwischenspeichern oder mit Funktionen (Version 2.0) bearbeiten. Der Wert wird ohne die umschließenden Tags übernommen.

<xsl:value-of select="Bezeichnung" />


<xsl:element name="art_nummer"><xsl:value-of select="ver_art" /> - <xsl:value-of select="ver_nummer" /></xsl:element>
Durch diesen Anweisungsblock wird ein neues Element in der Ausgabedatei mit dem Namen art_nummer erstellt. Die Werte der Felder ver_art und ver_nummer werden ausgelesen und zwischen das neue umschließende Element geschrieben. Zwischen den beiden Werten wird ein Gedankenstrich platziert.

Bedingte Ausführung von Anweisungen

Damit Elemente in der Ausgabedatei in Abhängigkeit von bestimmten Werten in der Ausgangsdatei erstellt werden, kann mit Bedingungen gearbeitet werden. XSLT kennt zwei unterschiedliche Anweisungen für eine bedingte Ausführung.

einfache Bedingung

Die einfache Bedingung kennt nur einen Zweig, der ausgeführt wird, wenn ein Test positiv ist: <xsl:if test="Bedingung">...</xsl:if>. Bedingung steht dabei für einen logischen Ausdruck, z. B. einen Vergleich. Damit zwei Werte verglichen werden können, benötigt man unterschiedliche Operatoren.


<xsl:if test="ver_titel2 != ''"><xsl:copy-of select="ver_titel2" /></xsl:if>
Hier wird geprüft, ob ver_titel2 nicht leer ist. Wenn also ein Text enthalten ist, wir dieser in die Ausgabedatei kopiert.

XSLT kennt keine else-Anweisung. Man kann dies aber durch eine Fallunterscheidung umgehen.

Fallunterscheidungen - mehrere Bedingungen

Es ist auch möglich eine komplexere Fallunterscheidung aufzubauen, die dann zu verschiedenen Bedingungen jeweils andere Ergebnisse liefert. Anders als bei <xsl:if>...</xsl:if> gibt es bei der Fallunterscheidung die Möglichkeit einen Anweisungsblock aufzurufen, wenn keiner der vorangegangenen Fälle zutrifft. So lässt sich auch ein else-Block aufbauen.

<xsl:choose>
	<xsl:when test="Bedingung_1">...</xsl:when>
	<xsl:when test="Bedingung_2">...</xsl:when>
		...
	<xsl:when test="Bedingung_n">...</xsl:when>
	<xsl:otherwise>...<xsl:otherwise>
</xsl:choose>

Mit <xsl:choose>...</xsl:choose> wird ein Block mit einer Fallunterscheidung aufgebaut. Die einzelnen Bedingungen werden mit <xsl:when test="Bedingung_x">...</xsl:when> aufgebaut. Trifft keine der Bedingungen zu, wird der Block <xsl:otherwise>...</xsl:otherwise> ausgeführt.


<xsl:choose>
	<xsl:when test="ver_titel2 != ''"><xsl:copy-of select="ver_titel2" /></xsl:when>
	<xsl:when test="ver_beschreibung_2" != ''"><xsl:element name="ver_titel2"><xsl:value-of select="ver_beschreibung_2" /></xsl:element></xsl:when>
</xsl:choose>
Hier wird zunächst geprüft, ob ver_titel2 einen Wert enthält. Ist dies der Fall, wird eine Kopie von ver_titel2 erstellt. Falls ver_titel2 leer ist, wird die nächste Bedingung überprüft. Ist in dieser ver_beschreibung_2 nicht leer, wird ein Element mit dem Namen ver_titel2 erzeugt und der Wert aus ver_beschreibung_2 in das neue Element geschrieben. Sind beide Felder leer, erhält die Ausgabedatei für diese Veranstaltung auch keinen ver_titel2. Für InDesign ist dies wichtig, würde ein leerer ver_titel2 in der Ausgabedatei stehen, würde InDesign auch für ein leeres Feld einen Platzhalter einbauen.


Arbeiten mit Variablen

Manchmal ist es sinnvoll Werte zwischenzuspeichern und diese dann an unterschiedlichen Stellen wieder aufzurufen. Mit <xsl:variable name="Bezeichner">...</xsl:variable> ist dies möglich. Der Name der Variablen wird mit Bezeichner festgelegt. Im Anweisungsblock zwischen den umschließenden Tags wird dann der Inhalt der Variablen aufgebaut.


<xsl:variable name="tab"><xsl:text> </xsl:text></xsl:variable>
Damit wir eine Variable tab angelegt. Der Inhalt ist ein Textelement, dessen Inhalt ein Tabulatorzeichen ist. Auf diese Variable kann dann mit <xsl:value-of select="$tab" /> zugegriffen werden. Eine praktische Anwendung davon ist die Kombination mehrerer Felder in einem neuen Ausgabefeld. Die Inhalte der Eingabefelder wird dann durch ein Tabulator getrennt. In InDesign stellt man dann die Tabulatoren in den Absatzformaten entsprechend ein.

Funktionen zur Verarbeitung von Feldern (Version 2.0)

Möchte man die Inhalte von Feldern noch weiter verändern, benötigt man einen Compiler, der die Version 2.0 von XSLT unterstützt. Hier sind nur wenige Funktionen beschrieben, mit denen man den Text verändern kann. Eine detailierte Beschreibungen der Funktionen findet sich unter http://www.xsltfunctions.com/.

fn:replace(string, pattern, replace)

Mit dieser Funktion kann der Inhalt eines Feldes verändert werden.


<xsl:value-of select="fn:replace(fn:replace(ver_geb_betrag, '\.', ','), ',00', )" /></xsl:element><xsl:text> Euro</xsl:text>
Mit diesem Ausdruck werden im Feld ver_geb_betrag Punkte durch Kommas ersetzt und Nachkommastellen gelöscht, wenn sie ,00 sind. Und hinten wird noch Euro angehängt.


<xsl:variable name="termine"><xsl:value-of select="ver_termine"/></xsl:variable>
<xsl:variable name="newline"><xsl:text>
</xsl:text></xsl:variable>
<xsl:variable name="delimiter">[<xsl:value-of select="ver_delimiter"/>]</xsl:variable>
<xsl:element name="termine"><xsl:value-of select="fn:replace(fn:replace($termine, $delimiter, $newline), ' von', ',')"/></xsl:element>
In der Variablen termine wird der Wert aus ver_termine zwischengespeichert. Die Variable newline erhält ein Textelment, dessen Inhalt ein Zeilenumbruch ist. Das Trennzeichen aus Kiribati wird in der Variablen delimiter gespeichert. Die Zeichen [...] sind notwendig, da das Trennzeichen in Kiribati der senkrechte Strich '|' ist. In XSLT bezeichnet dieser jedoch eine Schnittmenge. Würde man die Klammern nicht setzen, bricht der Compiler mit einer Fehlermeldung ab. Anschließend werden die Trennzeichen durch das Zeichen neue Zeile mithilfe von fn:replace($termine, $delimiter, $newline) ersetzt. Außerdem wird, ebenfalls mit einer fn:replace-Anweisung, von durch ein Komma ersetzt.

XML-Daten filtern und aufbereiten

Version 1.0

XML-Datei und Stylesheet Version 1.0 direkt in InDesign importieren

XML-Datei mit einem Compiler bearbeiten

Stylesheet Version 2.0 mit Saxon kompilieren

Weiterführende Links