xsl:with-param

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

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

 

Mit Hilfe der Instruktion xsl:with-param kann an eine xsl:param-Instruktion in einer Template-Regel, die im gleichen Kontext aufgerufen wird, ein Parameterwert übergeben werden.

Klassifizierung Sub-Instruktion
Funktionsgruppe Parameterübergabe
Einführung XSLT 1.0

Position im Stylesheet und erlaubte Inhalte:

xsl:with-param tritt als Sub-Instruktion innerhalb von xsl:apply-templates und xsl:call-template auf. Seit XSLT 2.0 ist sie auch als Inhalt von xsl:apply-imports erlaubt (in XSLT 1.0 ausdrücklich nicht!) sowie im Inneren der neuen Instruktion xsl:next-match.

Das Element enthält einen optionalen Sequenzkonstruktor, der einen temporären Baum erzeugt, der als Wert dem Zielparameter übergeben wird. Hingegen muss die Instruktion leer sein, wenn ein select-Attribut vorhanden ist. In diesem Fall wird der Wert übergeben, der sich aus der Auswertung des XPath-Ausdrucks des select-Attributs ergibt.

Ist weder ein Sequence Constructor als Inhalt noch ein select-Attribut vorhanden, so übergibt die Instruktion an den Zielparameter die leere Sequenz.

Attribute:

Es gelten die Standardattribute. Zusätzlich besitzt xsl:with-param die drei optionalen Attribute select, as und tunnel und das obligatorische Attribut name.

as

Wert

sequence-type

Verwendung

optional

Einführung

XSLT 2.0

Das as-Attribut legt den Datentyp des zu übergebenden Parameterwertes fest. Der Attributwert muss einen Sequence-Type nach XPath 2.0 bezeichnen. Wird das as-Attribut verwendet, so muss der übergebene Wert dem vorgegebenen Typ entsprechen.

Ist dies nicht der Fall, so wird eine Typkonvertierung vorgenommen. Ein Fehlschlagen der Konvertierung wird entsprechend als Typfehler gewertet (ERR XTTE0590). Ist kein as-Attribut vorhanden, so wird der Wert des Parameters entsprechend dem ausgewerteten select-Ausdruck bzw. dem enthaltenen Sequenzkonstruktor unverändert übernommen.

Hinweis: Das as-Attribut existiert nicht in XSLT 1.0.

name

Wert

qname

Verwendung

obligatorisch

Einführung

XSLT 2.0

Ein String in Form eines QName; der Bezeichner der xsl:param-Instruktion, an die der Wert übergeben werden soll. Der Name ist frei wählbar, allerdings ist es im Kontext von xsl:call-template ein Fehler, wenn kein Zielparameter des gleichen Namens existiert (dieses Verhalten wurde in XSLT 2.0 eingeführt).

Im Kontext des Aufrufs dürfen Variablen oder Parameter gleichen Namens im Scope sein, da xsl:with-param nicht der Deklaration, sondern nur zum Aufruf von Parametern dient (für rekursiv arbeitende Template-Regeln kann eine entsprechende Überschneidung sogar erforderlich sein).

select

Wert

xpath-expression

Verwendung

optional

Einführung

XSLT 1.0

Ein XPath-Ausdruck, der gemäß des aktuellen Kontexts ausgewertet wird und den an den Parameter zu übergebenden Wert bestimmt. Sobald das select-Attribut verwendet wird, darf die Instruktion keinen Inhalt (Sequenzkonstruktor) besitzen.

tunnel

Wert

"yes" | "no"

Verwendung

optional

Einführung

XSLT 2.0

Das tunnel-Attribut legt fest, ob der übergebene Wert als neuer Wert eines Tunnelparameters innerhalb des Tunnelparameterstroms nicht nur dem aufgerufenen Template, sondern auch diesem nachgeordneten Templates (d.h. von diesem direkt oder indirekt aufgerufenen) zur Verfügung stehen soll. Defaultwert ist "no", d.h., der übergebene Wert wird dem Tunnelstrom normalerweise nicht hinzugefügt.

Wird dagegen tunnel="yes" festgelegt, so steht der Wert unter dem festgelegten Parameternamen in der Aufrufkette all jenen xsl:param-Instruktionen gleichen Namens zur Verfügung, die ebenfalls das tunnel-Attribut mit Wert tunnel="yes" gesetzt haben.

Hinweis: Das tunnel-Attribut existiert nicht in XSLT 1.0.

Verwendungszweck:

Mit Hilfe der Instruktion xsl:with-param ist es möglich, einer Template-Regel bei ihrer Aktivierung einen Wert zu übergeben, der in einem dort vorliegenden lokalen Parameter xsl:param gespeichert wird. Der lokale Defaultwert des Parameters wird dabei überschrieben. Der Parame­terwert wird an denjenigen Parameter übergeben, dessen QName in der xsl:with-param-Instruktion durch deren name-Attribut genannt wird.

Bestimmung des zu übergebenden Wertes:
Die Instruktion erzeugt einen temporären Baum, der als Wert dem Zielparameter in der aufgerufenen Tem­plate-Regel übergeben wird (es könnte natürlich auch ein einfacher Stringwert etc. sein.). Die Erzeugung des Wertes gleicht im Wesentli­chen derjenigen bei xsl:variable oder xsl:param. Der Kontext der Wert­erzeugung entspricht dem der umgebenden Template-Regel, in der der Aufruf steht.

Der zu übergebende Wert kann über zwei Wege bestimmt werden:

  • Mittels des optionalen select-Attributs.
  • Mittels eines Sequenzkonstruktors, der den optionalen Inhalts der Instruktion darstellt.

Die Instruktion muss entweder ein select-Attribut oder einen Inhalt besitzen – beides gleichzeitig ist nicht gestattet.

Erlaubt, allerdings selten sinnvoll, ist die Abwesenheit des select-Attributs bei gleichzeitig leerer Instruktion. In diesem Fall wird als Wert die leere Sequenz übergeben (XSLT 1.0: der leere String), der Defaultwert des Zielparameters also ebenfalls überschrieben.

Verwendungskontext:
Die Instruktion xsl:with-param kann in verschie­denen Instruktionen eingesetzt werden, die dazu dienen, eine Template-Regel zu aktivieren. In XSLT 1.0 sind es die Instruktionen xsl:apply-templates und xsl:call-template, in XSLT 2.0 kommen zu diesen beiden xsl:apply-imports und xsl:next-match hinzu. Der Einsatz erfolgt prinzipiell so:

<xsl:apply-templates>
   <xsl:with-param name="param1" select="$wert1"/>
   <xsl:with-param name="param2" select="$wert2"/>
   <!-- weitere Parameterübergaben: -->
   ...
</xsl:apply-templates>

Neben der hier exemplarisch gezeigten Instruktion xsl:apply-templates kann jede andere der oben angegebenen Instruktionen verwendet werden. Es dürfen hierbei beliebig viele xsl:with-param-Instruktionen in Folge enthal­ten sein. Ihre Reihenfolge ist irrelevant und muss nicht mit der Reihenfolge der Parameterdeklarationen im Zieltemplate korrespondieren – die Zuordnung des Wertes erfolgt allein über den QName der Instruktion bzw. des Parameters.

Es ist aus diesem Grund nicht erlaubt, dass innerhalb eines Aufrufes zwei xsl:with-param-Instruktionen den gleichen QName verwenden. Dies gilt ausdrücklich auch dann, wenn der eine von ihnen ein tunnel-Attribut mit Wert tunnel="yes" besitzt und der andere nicht.

Existiert kein entsprechender Zielparameter in der aufgerufenen Template-Re­gel, so wird der Wert verworfen und die entsprechende xsl:with-param-Instruktion ignoriert.

Eine Ausnahme zu dieser Regel ist die Instruktion xsl:call-template, die das Vorhandensein eines entsprechenden Zielparameters zwingend vorschreibt und im Fehlerfall die Stylesheetverarbeitung verweigert (statischer Fehler ERR XTSE0680). Es ist jedoch kein Fehler, wenn einem existierenden lokalen Parameter kein Wert überge­ben wird (es sei denn, dessen required-Attribut hat den Wert "yes"), da in diesem Fall dessen Defaultwert verwendet werden kann.

Hinweis: Dieses rigorose Verhalten ist neu in XSLT 2.0. In XSLT 1.0 wird der erfolglose Versuch einer Parameterübergabe innerhalb von xsl:call-tem­plate noch ebenso wohlwollend ignoriert wie innerhalb von xsl:apply-templates.

Tunnelparameter
Parameterwerte können von einer Template-Regel zur anderen auch in Form so genannter »Tunnelparameter« weitergegeben werden. Diese werden ebenfalls mit xsl:with-param deklariert, jedoch muss diese Instruktion zusätzlich über ein tunnel-Attribut mit Wert tunnel="yes" verfü­gen. Der entsprechend übergebene Wert wird dem Tunnelstrom hinzugefügt und steht im aufgerufenen Template zur Verfügung, jedoch auch in diesem untergeordneten (also durch dieses aufgerufenen) Templates, ohne an diese explizit weitergegeben werden zu müssen. Der Parameterwert »durchtunnelt« gewissermaßen die dazwischen liegenden, weiterführenden Templateaufrufe.

Ein Tunnelparameter ähnelt hierin einem globalen Parameter; er kann jedoch mit einem neuen Wert belegt werden, wenn die ihn erzeugende xsl:with-param-Instruktion neu instanziiert wird. Befindet sich zu diesem Zeitpunkt bereits ein Parameter des gleichen Namens im Tunnelstrom, so wird dessen Wert für die Gültigkeitsdauer des neuen Parameters überschrieben (der alte Wert ist jedoch nicht gelöscht, sondern wieder zugänglich, sobald das Tem­­plate, das den neuen Wert erzeugt, und dessen untergordnete Templates abge­arbeitet sind).

Ein Tunnelparameter kann nur von einer xsl:param-Instruktion aufgefangen werden, die erstens den passenden Namen besitzt und zweitens ebenfalls über ein tunnel-Attribut mit Wert "yes" verfügt. Auch wenn der Parameterwert »unterwegs« ausgelesen wurde, steht er anschließend im Tunnelstrom weiter­hin für untergeordnete Templates zur Verfügung.

Ein explizit übergebener Wert hat im Zweifelsfall Vorrang vor einem Tunnel­wert – ein xsl:param mit tunnel="yes" nimmt also einen (auch ohne tunnel-Attribut) direkt übergebenen Wert entgegen, auch wenn im Tunnelstrom ein gleich benannter Parameterwert vorhanden sein sollte (solche implizit überge­benen Dubletten sind gestattet).

Die Möglichkeit, in einem Template zwei gleich benannte Parameter zu ver­wenden, auch wenn der eine ein tunnel-Attribut besitzt, besteht ausdrücklich nicht. Man kann also in keinem Fall gleichzeitig einen direkt übergebenen und einen Tunnelwert nutzen, wenn beide denselben (expandierten) Bezeichner haben.

Beispiele:

Beispiel 1 – Wertübergabe aus xsl:call-template:

<xsl:call-template name="textformatierung">
  <xsl:with-param name="trennstring"> *** </xsl:with-param>
</xsl:call-template>
<xsl:template name="textformatierung">
  <xsl:param name="trennstring"> – - – </xsl:param>
  ...
</xsl:template>

Hier wird mittels xsl:with-param einem lokalen Parameter in einer benann­ten Template-Regel ein Wert übergeben und der dort lokal vorliegende Default­wert überschrieben.

Beispiel 2 – Statischer Fehler in Zusammenhang mit xsl:call-template:

<xsl:call-template name="beispiel">
  <xsl:with-param name="hallo">Hallo Template</xsl:with-param>
</xsl:call-template>
<xsl:template name="beispiel">
  <xsl:param name="benoetigter_wert" required="yes"/>
  ...
</xsl:template>

Dieser Aufruf verursacht in XSLT 2.0 aus zwei Gründen einen statischen Feh­ler – zum einen existiert der aus xsl:call-template übergebene Parameter $hallo im Zieltemplate nicht, zum anderen wird ein weiterer, dort erwarteter und mit required="yes" gekennzeichneter Parameter $benoetigter_wert nicht übergeben.

Anmerkung: In XSLT 1.0 ist dieses Beispiel irrelevant – erstens ist es dort gestattet, aus xsl:call-tem­plate einen Parameterwert »ins Leere« zu schicken, zweitens besitzt xsl:param noch kein required-Attribut.

Beispiel 3 – xsl:with-param in xsl:call-template:

<xsl:template name="listenausgabe">
  <!-- Default, falls kein Wert übergeben wird: -->
  <xsl:param name="format">1. </xsl:param>
  <div>
    <xsl:number format="{$format}"/>
    <xsl:apply-templa­tes />
  </div>
</xsl:template>
<!-- für einfache Listen: -->
<xsl:template match="liste/listenelement">
  <xsl:call-template name="listenausgabe"/>
</xsl:template>
<!-- für verschachtelte Listen: -->
<xsl:template match="liste//liste/listenelement">
  <xsl:call-template name="listenausgabe">
    <xsl:with-param name="format">a. </xsl:with-param>
  </xsl:call-template>
</xsl:template>
  

Hier wird ein benanntes Template verwendet, um eine Liste zu formatieren. Je nach Verschachtelungsgrad wird beim Aufruf mit xsl:with-param ein Parame­ter übergeben. Wird kein Parameter übergeben, so tritt der im Inneren der Parameterdeklaration bei xsl:param gesetzte Defaultwert "1. " in Kraft.

Beispiel 4 – xsl:with-param in xsl:apply-templates:

<xsl:template match="kapitel" mode="rot">
  <xsl:apply-templates select="abschnitt">
    <xsl:with-param name="farbe">red</xsl:with-param>
  </xsl:apply-templates>
</xsl:template>
<!-- bei direktem Aufruf bleibt die Schrift schwarz -->
<xsl:template match="abschnitt">
  <xsl:param name="farbe">black</xsl:param>
  <p style="color:{$farbe}"><xsl:apply-templates/></p>
</xsl:template>
  

Hier wird xsl:with-param im Inneren von xsl:apply-templates eingesetzt. Wird das abschnitt-Template auf gewöhnlichem Wege (ohne Parameter) akti­viert, so wird der Defaultwert für die Farbdarstellung verwendet. Soll ein Kapi­tel im Templatemodus "rot" verarbeitet werden, so wird die obere Template-­Regel aufgerufen. Diese stellt mittels xsl:apply-templates ebenfalls eine Nodesequenz für das abschnitt-Template zusammen, übergibt aber gleichzei­tig einen Parameterwert, der den lokalen Wert der Farbdarstellung über­schreibt.

Zu beachten ist, dass der Templatemodus "rot" nicht weitergereicht wird (dies machen nur Default-Templates automatisch, siehe xsl:template). Hierfür müsste xsl:apply-templates ebenfalls ein mode-Attribut besitzen.

Elementdefinition:

XSLT 1.0:

<!-- Category: sub-instruction -->
<xsl:with-param 
     name = qname 
     select = expression>

     <!-- Content: template -->
</xsl:with-param>

XSLT 2.0:

<!-- Category: sub-instruction -->
<xsl:with-param
     name = qname
     select? = expression
     as? = sequence-type
     tunnel? = "yes" | "no">

     <!-- Content: sequence-constructor -->
</xsl:with-param>
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