Globale Variablen und Parameter

(Auszug aus "XSLT 2.0 & XPath 2.0" von Frank Bongers, Kapitel 3.)

Sowohl xsl:variable als auch xsl:param dürfen im Stylesheet als Toplevel-Elemente erscheinen. Geschickterweise stellt man ihre Deklarationen an den Beginn des Stylesheets, woraufhin sie für alle folgenden Elemente und deren Child-Elemente gültig sind. Mit anderen Worten, da ja alle xsl:template-Ele­mente following-siblings der Variablen- oder Parameter-Deklaration sind, gilt die Variable in allen folgenden Templates. Man spricht von globalen Variablen, weil sie demzufolge überall im Stylesheet ausgelesen werden können.

Toplevel-Parameter sind etwas anders

Ein globaler Parameter unterscheidet sich von einer globalen Variable im Gül­tigkeitsbereich nicht. Er kann aber, wenn nicht der Default-Wert verwendet werden soll, mit einem anderen Wert gefüllt werden, der im Fall eines globalen Parameters nicht durch xsl:with-param geliefert wird (und auch nicht geliefert werden kann), sondern von außer­halb des Stylesheets kommen muss.

In XSLT selbst ist es nicht festgelegt, auf welche Art der Wert übergeben wird. Die XSLT 2.0-Prozessoren AltovaXML und Saxon nehmen Parameter auch direkt über die Kommandozeile entgegen.

Saxon 9.0:

java net.sf.saxon.Transform  -s:quelldokument  -xsl:stylesheetname  -o:zieldokument paramname=paramwert

AltovaXML:

AltovaXML  -xslt2 stylesheetname  -in quelldokument  -out zieldokument  -param paramname=paramwert

Bei Altova ist zu beachten, dass der String des Parameterwerts in Anfühungszeichen stehen muss, sobald er Leerzeichen enthält (sei es in Dateinamen oder, wie hier, in Ausdrücken).

Cocoon entnimmt Parameterwerte dem Query-String des URL, etwa folgendermaßen:

nehme_parameter.xml?parametername=wert

Hierbei ist zu beachten, dass, trotz des Aufrufs in Zusammenhang mit dem XML-Dokument, nicht dieses den Parameter übernimmt, sondern das verarbei­tende XSLT-Stylesheet:

<!-- Deklarationsebene -->
<xsl:param name="ausrichtung">left</xsl:param>
<!-- Eines von vielen Templates -->
<xsl:template match="para">
  <p align="{$ausrichtung}"><xsl:apply-templates/></p>
</xsl:template>

Hier wird ein globaler Parameter $ausrichtung deklariert, der in einem Attri­butwert-Template eines Literal Result Elements einer Template-Regel eingesetzt wird. Sein Default-Wert ist "left".

Außer in diesem einen Template wäre der Parameter auch in allen anderen Templates des Stylesheets gültig. Würde von außen ein anderer Wert überge­ben, so könnte hiermit die Textausrichtung für alle Template-Regeln geändert werden, die diesen Parameter referenzieren.

Lokale Variablen und Parameter in Templates

Die Elemente xsl:variable und xsl:param sind auch innerhalb von Temp­late-Blöcken erlaubt. Dort deklarierte Variablen und Parameter haben dann aber einen gegenüber den globalen Variablen stark eingeschränkten Gültigkeits­bereich. Ihr Scope ist nur auf »ihren« Template-Block beschränkt und dort auf die der Deklaration folgenden Geschwisterelemente.

Aus diesem Grund deklariert man sie, sofern möglich, am besten direkt zu Beginn des Template-Blocks. Für lokale xsl:param-Elemente ist dies sogar obligatorisch.

Der Versuch, eine lokale Variable außerhalb ihres Gültigkeitsbereichs auszule­sen, führt zu einem Fehler. Eine für ein Template deklarierte Variable kann nicht in einem folgenden Template ausgewertet werden:

<xsl:template name="das_eine_template">
  <xsl:variable name="die_variable" select="der_wert"/>
  <!-- bezieht sich auf lokale Variable: -->
  Lokal: <xsl:value-of select="$die_variable"/>
</xsl:template>
<xsl:template name="anderes_template">
  <!-- Folgendes kennt man hier nicht mehr: --> 
  Oops: <xsl:value-of select="$die_variable"/>
</xsl:template>

Die folgende Abbildung verdeutlicht den Gültigkeitsbereich globaler und lokaler Parameter. Während die globale Variable $var_global und der Parameter $para_global in allen Template-Regeln zur Verfügung stehen (hellgrau hinterlegt), beschränkt sich die Gültigkeit lokaler Größen wie $var_a und $para_b auf deren aktuelle Template-Regel – und zwar auf die Befehle nach deren Deklarierung (dunkelgrau hinterlegt). Sie stehen benachbarten Template-Regeln nicht zur Verfügung, können aber, wie dies für $var_a geschieht, beim Aufruf einer anderen Regel als Parameter an diese übergeben werden.

Gültigkeitsbereich von Parametern und Variablen

Abbildung: Gültigkeitsbereich von Parametern und Variablen.

Lokales Überschreiben – binding shadow von Variablen

Eine Variable ist ein an einen Namen »gebundener« Wert. Bei einer »normalen« Programmiersprache entspricht das »Binden« eines neuen Werts an einen bereits verwendeten Variablennamen einer Neuzuweisung des Werts. Dies ist in XSLT von Prinzip her nicht möglich. Es existiert also auch kein für diesen Zweck gedachter Operator.

Unter bestimmten Bedingungen ist es jedoch möglich, einen bereits verwende­ten Variablennamen (wobei es keine Rolle spielt, ob dieser einer Variablen oder einem Parameter zugeordnet ist) scheinbar neu zu belegen, und zwar, wenn es sich bei der »alten« Variable um eine globale und bei der »neuen« um eine lokale Variable handelt.

In diesem Fall »verdeckt« die lokale Variable innerhalb ihres Template-Blocks die globale Variable. Man spricht von einem so genannten binding shadow. Das Shadowing ist jedoch nur vorübergehend: Nach Ende der Template-Laufzeit gilt wieder der Wert der globalen Variable.

Alle anderen Versuche, zwei gleich benannte Variablen oder Parameter (dies wird, wie gesagt, nicht unterschieden – der Aufruf ist ja identisch) führen zu einer Fehlermeldung. Zwei gleich benannte Variablen können also weder glo­bal noch lokal auftreten. Das folgende Beispiel verursacht daher eine Fehler­meldung:

<xsl:template name="so-gehts-nicht">
  <xsl:param name="dublette" select="der_wert"/>
  ...
  <!-- und jetzt gibt’s einen Fehler: -->
  <xsl:variable name="dublette" select="anderer_wert"/>
  ...
  <!-- worauf bezieht sich dies? -->
  Lokal: <xsl:value-of select="$dublette"/>
  ...
</xsl:template>

Das »Überschreiben« globaler Variablen hingegen ist erlaubt:

<!-- globale Variable: -->
<xsl:param name="dublette" select="der_wert"/>
<xsl:template name="so-gehts">
  <!-- verdeckt die globale Variable: -->
  <xsl:variable name="dublette" select="anderer_wert"/>
  ...
  <!-- bezieht sich auf lokale Variable: -->
  Lokal: <xsl:value-of select="$dublette"/>
</xsl:template>
<xsl:template name="anderes_template">
  <!-- referenziert die globale Variable: -->
  Global: <xsl:value-of select="$dublette"/>
</xsl:template>

Wo dürfen Variablen verwendet werden?

Nach ihrer Deklarierung dürfen Variablen und Parameter an zwei Orten refe­renziert werden:

  • In einem Attribut eines XSLT-Elements
    In allen Attributen, die unmit­telbar XPath-Ausdrücke aufnehmen können, werden auch Variablen oder Parameter ausgewertet. In diesen Fällen kann der Variablenaufruf einfach in das Attribut geschrieben werden:
<xsl:for-each select="$variable">
  ...
</xsl:for-each>
  • In einem Attributwert-Template
    Sollen Variablen an anderen Stellen interpretiert werden, so müssen sie in den geschweiften Klammern eines Attributwert-Templates stehen (Anmerkung: Eine Auflistung aller Attribute von XSLT-Instruktionen, die AVTs erlauben, befindet sich unter der XSLT 2.0-Referenz):
<xsl:element name="{$variable}">
  ...
</xsl:element>
Tipp der data2type-Redaktion:
Zum Thema XSLT bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:

Copyright © Galileo Press, Bonn 2008
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "XSLT 2.0 & XPath 2.0 ― Das umfassende Handbuch" denselben Bestimmungen wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Galileo Press, Rheinwerkallee 4, 53227 Bonn