Probleme bei der Portierung von 1.0 zu 2.0 vermeiden

(Auszug aus "XSLT Kochbuch" von Sal Mangano)

Problem

Nicht jedes 1.0-Stylesheet funktioniert transparent in 2.0.

Lösung

Falls Sie 1.0-Stylesheets nach 2.0 portieren müssen, sollten Sie auf verschiedene Stolpersteine achtgeben. Einige dieser Probleme können mit Hilfe des XSLT 1.0-Kompatibilitätsmodus ausgeräumt werden, das heißt, indem Sie version=1.0 im Stylesheet-Element <xsl:stylesheet version="1.0"> verwenden. Falls Sie jedoch damit beginnen wollen, alte Stylesheets nach 2.0 zu migrieren, gibt es andere Lösungen für diese Inkompatibilitäten, wie gleich erklärt wird.

Achtung!
XSLT 2.0-Prozessoren sind nicht dazu verpflichtet, den Abwärtskompatibilitätsmodus zu unterstützen, obwohl die meisten es wahrscheinlich tun werden. Wird er nicht unterstützt, gibt der Prozessor eine Fehlermeldung aus.

Sequenzen werden nicht transparent in atomare Objekte umgewandelt

Stellen Sie sich das Fragment <xsl:value-of select="substring-before(Name, ' ')"/> vor. Was passiert, wenn dies in einem Kontext ausgewertet wird, der mehr als ein Name-Element enthält? In XSLT 1.0 würde nur das erste verwendet werden, der Rest würde ignoriert werden. XSLT 2.0 dagegen ist strenger und signalisiert einen Typfehler, weil das erste Argument substring-before nur eine Sequenz aus 0 oder 1 Strings sein kann.

Um dieses Problem zu beheben, sollten Sie sich angewöhnen, <xsl:value-of select="substring-before(Name[1], ' ')"/> zu schreiben. Andererseits wollen Sie vielleicht von diesen Fehlern in Kenntnis gesetzt werden, da sie einen Bug in der Art und Weise signalisieren könnten, wie das Stylesheet oder seine Eingabedokumente geschrieben sind. Eine alternative Lösung, die unter bestimmten Umständen anwendbar wäre, besteht darin, mehrere Knoten zu einem einzigen Knoten zu kombinieren, bevor die Sequenz einer Funktion präsentiert wird, die nur einen Knoten erwartet. Zum Beispiel würde <xsl:value-of select= "substring-before(string-join(Name), ' ')"/> keinen Fehler erzeugen.

Typen werden nicht transparent in andere Typen umgewandelt

Auf dem Gebiet der Typumwandlungen war XSLT 1.0 ziemlich locker. Wenn eine Funktion eine Zahl erwartete und Sie einen String angaben, tat es sein Bestes, um den String in eine Zahl umzuwandeln und umgekehrt. Das galt auch für Konvertierungen zwischen Booleschen Werten und Integer-Werten oder Booleschen Werten und Strings. Wenn Sie den 1.0-Kompatibilitätsmodus einsetzen, können Sie sich das alte Verhalten bewahren. Allerdings können Sie Werte auch explizit konvertieren:

<xsl:variable name="a" select=" '10' "/>
<xsl:value-of select="sum($a, 1)"/> <!-- Fehler -->
<xsl:value-of select="sum(number($a), 1)"/> <!-- OK -->

<xsl:value-of select="string-length(10)"/> <!-- Fehler -->
<xsl:value-of select="string-length(string(10))"/> <!-- OK -->
<xsl:value-of select="string-length(string(true( )))"/> <!-- OK, gleich 4 -->

<xsl:value-of select="1 + true( )"/> <!-- Fehler -->
<xsl:value-of select="1 + number(true( ))"/> <!-- OK, gleich 2 -->

Zusätzliche Parameter werden nicht ignoriert

Wenn Sie in XSLT 1.0 ein Template mit xsl:call-template aufgerufen haben und dabei Parameter übergaben, die das Template nicht definiert hat, wurden die zusätzlichen Parameter stillschweigend ignoriert. In 2.0 kommt es nun zu einem Fehler. Sie können diesen Fehler deaktivieren, indem Sie den 1.0-Kompatibilitätsmodus verwenden. Es gibt keine andere Abhilfe, als die zusätzlichen Parameter zu entfernen oder in das existierende Template Standardwerte einzufügen.

Eine strengere Prüfung der Semantik verursacht Fehler bei fragwürdigem Gebrauch

Beispiele dafür können sowohl bei der Anweisung xsl:number als auch bei der Anweisung xsl:template gesehen werden. Falls Sie die Attribute level und value zusammen in xsl:number benutzen, wird das Attribut level in 1.0 ignoriert, in 2.0 dagegen ist das ein Fehler. Ähnlich ist es mit xsl:template: Sie können priority oder mode in 2.0 nicht definieren, wenn kein match-Attribut definiert ist.

Diskussion

Die Verwendung des Abwärtskompatibilitätsmodus zum Korrigieren von Fehlern in 1.0-Stylesheets hat Folgen. Vor allem bedeutet es, dass sich einige Dinge anders verhalten. Im 1.0-Kompatibilitätsmodus

  • gibt xsl:value-of nur das erste Objekt einer Sequenz aus, anstatt alle Objekte, getrennt durch Leerzeichen.
  • gibt ein Attributwert-Template (z.B. <foo values="{foo}"/>) nur das erste Objekt einer Sequenz aus, anstatt alle Objekte, getrennt durch Leerzeichen.
  • wird bei Verwendung von xsl:number die erste Zahl in einer Sequenz ausgegeben, anstatt alle Zahlen, getrennt durch Leerzeichen.

Aus diesen Gründen wäre es sinnvoll, sich bei der Entwicklung neuer Stylesheets, die für einen 2.0-fähigen Prozessor gedacht sind, nicht auf den Abwärtskompatibilitätsmodus zu verlassen.

  

<< zurück vor >>

 

 

 

Tipp der data2type-Redaktion:
Zum Thema XSLT bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:

Copyright © 2006 O'Reilly Verlag GmbH & Co. KG
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "XSLT Kochbuch" 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.

O'Reilly Verlag GmbH & Co. KG, Balthasarstraße 81, 50670 Köln, kommentar(at)oreilly.de