Alternative in XPath: if - then - else
(Auszug aus "XSLT 2.0 & XPath 2.0" von Frank Bongers, Kapitel 2.)
In gewissem Rahmen können XPath-Ausdrücke gleichwertig zu umfangreicheren XSLT-Strukturen eingesetzt werden, wie im vorhergehenden Kapitel ansatzweise im Rahmen des »Maßschneiderns« von Sequenzen gezeigt wurde. In jenem Fall wurde eine Reihe von xsl:value-of und xsl:text durch eine einzige Instruktion xsl:value-of mit entsprechendem Sequenzausdruck ersetzt.
Eine ähnliche Substitutionsmöglichkeit liegt auch für xsl:if oder ein einfaches xsl:choose vor. Auch im Rahmen von XPath-Ausdrücken können Bedingungen (Conditional Expressions) erscheinen. Es handelt sich jedoch nur um einfache IF-THEN-ELSE-Konstrukte, mit denen ein SELECT, also xsl:choose mit mehreren xsl:when, nicht ohne Weiteres modelliert werden kann. Es ist hierfür jedoch möglich, XPath-IFs zu verschachteln:
if (bedingung) then (anweisung) else (alternative anweisung)
Der ELSE-Zweig ist nicht optional, kann aber die leere Sequenz sein:
if (bedingung) then (anweisung) else ()
Ein XPath-Ausdruck kann in manchen Fällen daher ein xsl:if oder aber auch ein xsl:choose mit einem xsl:when und xsl:otherwise ersetzen:
<xsl:value-of select="if (@isbn!='') then ('(ISBN: ', @isbn, ')') else ()"/>
Hier erfolgt die Prüfung und Ausgabe der ISBN-Nummer innerhalb eines Ausdrucks im select-Attribut von xsl:value-of. In der Bedingung, die in runden Klammern auf das if-Schlüsselwort folgt (test expression) wird, analog zum Ausdruck im test-Attribut von xsl:if oder xsl:when, Vorhandensein und Wert des isbn-Attributs geprüft.
Die Sequenz, die hier als Ausdruck nach dem Schlüsselwort then dient (then expression), wird ausgegeben, wenn die Bedingung erfüllt ist, ansonsten wird der Ausdruck nach dem else-Schlüsselwort (else expression) ausgewertet. In diesem Fall ist es die leere Sequenz, daher wird nichts ausgegeben. Dies entspricht xsl:if. Verwendet man einen nicht leeren else-Ausdruck, so wird in etwa ein xsl:choose nachgebildet.
Da entsprechende Ausdrücke die Tendenz besitzen, entweder länglich oder kryptisch zu werden, bietet sich an, sie entsprechend mit erklärenden Kommentaren zu erläutern. Ein XPath-Kommentar beginnt mit der Zeichenfolge (: und endet analog mit :).
<xsl:value-of select="if (@isbn!='') then ('(ISBN: ', @isbn, ')') else() (: in diesem Fall nichts ausgeben :)"/>
XPath-Kommentare können, im Gegensatz zu den Gepflogenheiten der meisten anderen Programmiersprachen, verschachtelt werden. Die ungewöhnliche, als »Smiley-Kommentare« belächelte Syntax ist die Folge davon, dass üblicherweise für Kommentarmarken eingesetzte Zeichen wie /, * oder # in XPath bereits anderweitig verwendet sind. (: In jedem Falle wird der Quelltext freundlicher. :)
Zeilenumbrüche innerhalb des Ausdrucks sind zwischen den einzelnen Token problemlos möglich; eine Notwendigkeit, alles in eine Zeile zu schreiben, besteht nicht. Hier ist das Äquivalent zu xsl:choose:
<xsl:value-of
select="if (@isbn!='')
then ('(ISBN: ', @isbn, ')')
else ('(ISBN-Nummer liegt nicht vor.)')"/>
Ausgegeben werden in allen Fällen Sequenzen, die von xsl:value-of übernommen und als Strings ausgegeben werden. Hierbei wird jeweils ein Leerzeichen zwischengesetzt. Dies kann per separator-Attribut geändert werden.
xsl:value-of: Pseudo-LREs mit disable-output-escaping
Gegenüber der XSLT-Version ist die Ausgabe zusätzlichen HTML-Markups erschwert, da Literal Result Elements nicht wirklich zur Verfügung stehen. (Anmerkung: XQuery kennt Elementkonstruktoren der Form element tagname {elementinhalt}, die in der XPath-Sektion der Sprache leider nicht verfügbar sind. Sonst könnte man hier statt <br/> etwa element br {} schreiben. Eine Erweiterung von XPath in dieser Richtung ist in naher Zukunft vermutlich nicht zu erwarten.) Folgender Versuch, in XSLT einen HTML-<br> vor der Ausgabe einzufügen, führt zu einem Fehler:
<!-- Dies hier stellt einen Syntaxfehler dar: -->
<xsl:value-of select="if (@isbn!='') then ('<br/>(ISBN: ', @isbn, ')') else ('<br/>(ISBN-Nummer liegt nicht vor.)')"/>
Die spitzen Tag-Klammern müssen in diesem Kontext zu <br/> escaped werden. Folgende Variante stellt zwar keinen Fehler dar. Die durch den XML-Parser vorübergehend zu <br/> unescapten Tags werden für die Ausgabe allerdings erneut maskiert, was im Browser wenig hilfreich ist:
<xsl:value-of select="if (@isbn!='') then ('<br/>(ISBN: ', @isbn, ')') else ('<br/>(ISBN-Nummer liegt nicht vor.)')"/>
Eben dieses Escaping kann jedoch unterbunden werden. xsl:value-of stellt hierfür das Attribut disable-output-escaping zur Verfügung. Mit dem Wert "yes" wird die erwünschte Ausgabe eines HTML-Tags erreicht:
<xsl:value-of select="if (@isbn!='') then ('<br/>(ISBN: ', @isbn, ')') else ('<br/>(ISBN-Nummer liegt nicht vor.)')" disable-output-escaping="yes"/>
Dieser Ausweg ist jedoch ausdrücklich mit Vorsicht zu genießen, da das Output-Escaping für alle von dieser Instruktionsinstanz ausgegebenen Inhalte deaktiviert ist, nicht nur für die hier gewünschten! Sollten sich in den restlichen Inhalten Sonderzeichen befinden, so könnten diese nicht maskiert werden. Eine mögliche Folge besteht darin, dass das Ergebnis kein wohlgeformtes XML bzw. XHTML mehr sein könnte.
<< zurück | vor >> |
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