Vorige Seite Hauptseite Nächste Seite
<xsl:variable |
name = qname |
select? = xpath-ausdruck |
as? = typ> |
<!-- Wert--> |
</xsl:variable |
theo
definiert, so bekommen wir den Wert der Variablen durch
$theo.
Das Attribut as erlaubt, den
Typ zu spezifizieren. Man kann Variable von jedem Typ haben; der
default ist allerdings string.
Man ist gut beraten, den Typ anzugeben.
Der Wert, der der Variablen zugewiesen wird, ist entweder der
Wert des in dem Tag eingeschlossenen Knotens, also zB
<xsl:variable |
as ="xs:int"> |
137 |
</xsl:variable> |
select
Ausdrucks. Es darf deswegen nicht gleichzeitig
ein select
Attribut vorhanden sein und der Knoten nicht leer.
Denn dann gibt es einen Konflikt zwischen zwei Zuweisungen.
Allerdings dürfen beide leer sein. In diesem Fall hat die
Variable den Wert einer leeren Zeichenkette.
Ich gebe hier ein instruktives Beispiel. Um die im Prozessor
verankerten Alphabetreihenfolgen zu tabellieren, habe ich eine
Datei geschrieben, die einfach nur die Buchstaben in irgendeiner
Reihenfolge enthält, etwa so.
<?xml version="1.0" |
<alphabet> |
<wort>c</wort> |
<wort>b</wort> |
<wort>q</wort> |
</alphabet> |
<?xml version="1.0" encoding="UTF-8"?>
|
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
exclude-result-prefixes="xs"
|
version="2.0">
|
<xsl:variable name="orig"
select="/alphabet/wort" as="xs:string*"/>
|
<xsl:variable name="ger"
as="xs:string*">
|
<xsl:perform-sort
select="$orig">
|
<xsl:sort
lang="de-DE"/>
|
</xsl:perform-sort>
|
</xsl:variable>
|
<xsl:variable name="hun"
as="xs:string*">
|
<xsl:perform-sort
select="$orig">
|
<xsl:sort
lang="hu-HU"/>
|
</xsl:perform-sort>
|
</xsl:variable>
|
<xsl:template match="/alphabet">
|
<html>
|
<head></head>
|
<body bgcolor="moccasin">
|
<h3>Das Alphabet</h3>
|
<table border="3">
|
<tr><td>Pos.</td><td>Original</td>
|
<td>de-De</td><td>hu-HU</td></tr>
|
<xsl:for-each select="$orig">
|
<xsl:variable name="i"
select="position()"/>
|
<tr><td>
<xsl:number value="$i" format="1."/></td>
|
<td><xsl:value-of select="$orig[$i]"/></td>
|
<td><xsl:value-of select="$ger[$i]"/></td>
|
<td><xsl:value-of select="$hun[$i]"/></td>
|
</tr>
|
</xsl:for-each>
|
</table>
|
</body>
|
</html>
|
</xsl:template>
|
</xsl:stylesheet> |
xsl:perform-sort
Gebrauch gemacht. Dies erlaubt, eine Liste zu ordnen. Das Ergebnis
ist wieder eine Liste, und diese weise ich einer Variablen zu. Das
Attribut as mit Wert
xs:string* darf hier nicht
fehlen, sonst denkt das Programm, ich will nur eine Zeichenkette.
(Der Stern * ist ein sogenannter
Typkonstruktor. typ*
bezeichnet Listen von Objekten vom Typ
typ.)
Anschließend gehe ich synchron durch alle Listen durch. Dabei
wird eine Variable i lokal
vereinbart und mit dem Wert position()
versehen. Der Wert wird dann ausgegeben und anschließend
jeder Liste witergegeben. (Auch hier wieder: ohne die Variable geht's
nicht, das habe ich probiert.) Man kann auch noch die Möglichkeiten
einer Formatierung von Zahlausgaben anschauen.
x7,
deklariert und ihr einen Wert zugewiesen, etwa 123, so kann man auf diesen
Wert anschließend zurückgreifen. Den Wert bekommt man mittels
$x7. Klarerweise ist der Wert
der Variable nicht verfügbar, bevor sie definiert wurde (es sei
denn, sie ist global). Jedoch ist die
Variable nicht unbegrenzt danach existent sondern besitzt eine gewisse
Lebensspanne, den sogenannten Skopus. In XSLT ist der Skopus einer
Variable durch das Tag begrenzt, in dem die Variable definiert worden
ist. Das bedeutet: ist die Variable unmittelbar nach einem Tag namens
<tag> deklariert worden,
dann endet der Skopus beim nächsten Auftreten von
</tag>.
Innerhalb ihres Skopus darf die Variable nicht erneut
definiert werden, das ergibt eine Fehlermeldung.
In XSLT kann man den Wert einer Variablen nicht ändern, deswegen ist
der Skopus ein wichtiges Instrument, um eine Variable tatsächlich
variabel zu halten. Hier ist die Idee. Gesetzt, wir wollen eine
Tabelle in HTML Format ausgeben. Wir wollen einen gewissen Wert,
sagen wir die Zeilennummer, in einer Zeile verfügbar machen.
Da sich die Zeilennummer ständig ändert, darf man die Variable
nicht global vereinbaren. Denn dann wird ihr ein Wert zugewiesen,
der nicht mehr zu ändern ist. Die Lösung besteht hier darin,
die Variable erst nach dem Tag
<tr> zu vereinbaren. In diesem Fall wird
ihr Wert für die gesamte Zeile (also bis zum nächsten
</tr>) zur
Verfügung stehen. Man kann das in der oberen Datei sehr schön
sehen. Innerhalb von <for-each>
wir die Variable i
dem Wert von position()
zugewiesen. Endet das Tag, dann wird ein neuer Knoten bearbeitet,
die Variable i wird dann aber
nicht neu zugewiesen: es ist lediglich so, dass mit Ende des ersten
Zyklus die Variable i verschwindet
und mit Beginn des neuen Zyklus eine neue Variable
i entsteht. Ihr Wert ist dann der Wert von
position(), welcher nunmehr
anders ist als der vorige.
<xsl:param |
name = qname |
select? = xpath-ausdruck |
as? = typ |
required? = "yes" | "no"> |
<!-- Wert--> |
</xsl:param> |
xsl:variable
ist die Möglichkeit festzulegen, ob der Parameter einen Wert haben
muss. Es gelten wiederum die Regeln wie bei Variablen: es darf
nicht gleichzeitig das Tag nichtleer sein und
select
anwesend. Allerdings dürfen diesmal beide leer sein, da der Wert
ja noch nicht festliegen muss.
Bei Templates haben wir noch eine Option mehr:
<xsl:param |
name = qname |
select = xpath-ausdruck |
as? = typ |
required? = "yes" | "no" |
tunnel? = "yes" | "no"> |
<!-- Wert--> |
</xsl:param> |
tunnel auf
yes gesetzt wird,
dann wird der Parameter an alle untergeordneten Prozeduren
weitergereicht. Das ist sehr nützlich, wenn man sich eine
Prozedur schreiben will, die verschiedene Stile der Ausgabe
hat.
Modi dienen zur Auswahl von Templates. Wir können Templates
zu gewissen Modi gruppieren um dann beim Aufruf
<xsl:apply-templates>
einen Modus anzugeben. Wenn wir also beim Aufruf den Modus spezifizieren,
werden nur Templates verwendet, die zu diesem Modus gehören. Zusätzlich
zu den frei verfügbaren Namen existieren drei spezielle "Modi":
#current,#default, sowie#all.
Die Befehle <xsl:apply-templates>
und <xsl:template> besitzen je
ein Attribut namens mode. Der Wert von
mode in
<xsl:template> darf eine
Liste von Modi sein (darunter #default)
oder #all.
Der Wert von mode in
<xsl:apply-templates> hingegen
darf nur ein einziger Modus sein oder
#current.
Man beachte also, dass Templates in mehrere Modi gruppiert
werden können, aber der Aufruf nur einen einzigen Modus
verwendet. Man mag sich überlegen, dass es nicht nötig ist,
beim Aufruf die Angabe von Listen von Modi anzugeben. Den
Effekt kann man durch die Einführung eines neuen Modus
erreichen, der alle in der Liste gegebenen Modi zusammenfasst.
So zum Beispiel ist #all
ein alles umfassender Modus.
Ist der Modus beim Template nicht gesetzt, wird der Wert
#default eingesetzt. Das
bedeutet, dass dieses Template immer dann verwendet wird, wenn in
<xsl:apply-templates>
kein Modus angegeben ist. Ist hingegen der Modus gesetzt und
enthält er nicht #default,
dann kann es nur dann werwendet werden, wenn
<xsl:apply-templates> einen
Modus aufruft, der in der Liste vorkommt. Sollte ein Template
einen Modus haben, der niemals aufgerufen wird, so ist das
kein Fehler. Es bedeutet lediglich, dass das Template niemals
angewendet wird (eine gute Möglichkeit, um Templates
zeitweilig zu inaktivieren, ohne den Code stark zu verändern).
Man sollte wissen, dass der Aufruf von
<xsl:apply-templates>
dazu führt, dass der XSLT-Prozessor versucht, ein geeignetes Template
zu finden. Dabei gibt es mehrere Sonderfälle:
<xsl:apply-templates>
wird auf alle Kinder angewendet, Parameter werden nach unten weitergreicht.
<xsl:value-of select="string(.)"/>
).
<xsl:apply-templates>
aufgerufen hat, aber der Prozessor bei diversen Tags nichts finden
kann.
Vorige Seite Hauptseite Nächste Seite