Zur Startseite Klute-Thiemann

edition W3C.de

XSL Transformations (XSLT) Version 1.0

Deutsche Übersetzung

18. März 2002

Diese Version:
http://www.edition-w3c.de/TR/1999/REC-xslt-19991116
Aktuelle Version:
http://www.edition-w3c.de/TR/xslt
Übersetzer:
Thomas Klute <thomas@klute.com>
Jens Thiemann <jens@thiemann.com>

Bei diesem Dokument handelt es sich um eine Übersetzung eines W3C-Textes. Dieser Text ist urheberrechtlich geschützt; bitte beachten Sie die nachfolgenden Hinweise des Originaldokuments. Die Rechte an der Übersetzung liegen bei den Übersetzern. Die Übersetzung hat keine durch das W3C legitimierte, normative Wirkung. Das einzige maßgebliche Dokument ist das englische Original.

Bitte senden Sie Fehler und Korrekturen zur deutschen Fassung an die Übersetzer.


W3C

XSL Transformations (XSLT) Version 1.0

W3C Recommendation 16. November 1999

Diese Version:
http://www.w3.org/TR/1999/REC-xslt-19991116 XML HTML
Aktuelle Version:
http://www.w3.org/TR/xslt
Vorherige Version:
http://www.w3.org/TR/1999/PR-xslt-19991008
http://www.w3.org/1999/08/WD-xslt-19990813
http://www.w3.org/1999/07/WD-xslt-19990709
http://www.w3.org/TR/1999/WD-xslt-19990421
http://www.w3.org/TR/1998/WD-xsl-19981216
http://www.w3.org/TR/1998/WD-xsl-19980818
Editor:
James Clark <jjc@jclark.com>

Zusammenfassung

Diese Spezifikation definiert die Syntax und Semantik von XSLT, einer Sprache zur Transformation von XML-Dokumenten in andere XML-Dokumente.

XSLT ist entwickelt worden, um als ein Bestandteil von XSL, einer Stylesheet-Sprache für XML, benutzt zu werden. Zusätzlich zu XSLT enthält XSL ein XML-Vokabular, um eine Formatierung zu spezifizieren. XSL spezifiziert das Layout eines XML-Dokuments, um unter Benutzung von XSLT zu beschreiben, wie das Dokument in ein anderes XML-Dokument, welches das Formatierungsvokabular benutzt, transformiert wird.

XSLT ist auch entworfen worden, um unabhängig von XSL benutzt zu werden. Jedoch ist XSLT nicht als vollständig universelle XML-Transformationssprache gedacht. Vielmehr ist sie primär für die Arten von Transformationen entwickelt worden, die benötigt werden, wenn XSLT als Teil von XSL benutzt wird.

Status dieses Dokuments

Dieses Dokument wurde von Mitgliedern des W3C und anderen interessierten Beteiligten geprüft und vom Direktor als W3C-Empfehlung gebilligt. Es ist ein stabiles Dokument und darf als Referenzmaterial verwendet oder als normative Referenz von einem anderen Dokument zitiert werden. Die Rolle des W3C bei der Erstellung dieser Empfehlung ist, die Spezifikation bekannt zu machen und ihre breite Anwendung zu fördern. Dies erhöht die Funktionsfähigkeit und Interoperabilität des Web.

Die Liste der bekannten Fehler [XSLT-errata] in dieser Spezifikation ist unter http://www.w3.org/1999/11/REC-xslt-19991116-errata verfügbar.

Kommentare zu dieser Spezifikation können an xsl-editors@w3.org gesendet werden; Archive der Kommentare sind verfügbar. Öffentliche Diskussionen über XSL bzw. XSL-Transformationen finden in der XSL-List Mailing-Liste statt.

Die englische Version dieser Spezifikation ist die einzig normative Version. Für Übersetzungen dieses Dokuments siehe http://www.w3.org/Style/XSL/translations.html.

Eine Liste der aktuellen W3C-Empfehlungen und anderer technischer Dokumente kann unter http://www.w3.org/TR eingesehen werden.

Diese Spezifikation ist als Teil der W3C Style activity erstellt worden.

Inhaltsverzeichnis

1 Einführung
2 Stylesheet-Struktur
    2.1 XSLT-Namensraum
    2.2 Stylesheet-Element
    2.3 Literale Ergebniselemente als Stylesheet
    2.4 Qualifizierte Namen
    2.5 Vorwärts-kompatibles Verarbeiten
    2.6 Kombination von Stylesheets
        2.6.1 Stylesheet-Inklusion
        2.6.2 Stylesheet-Import
    2.7 Einbettung von Stylesheets
3 Datenmodell
    3.1 Kinder des Wurzelknotens
    3.2 Basis-URI
    3.3 Nicht analysierte Entitys
    3.4 Entfernen von Leerräumen
4 Ausdrücke
5 Template-Regeln
    5.1 Verarbeitungsmodell
    5.2 Muster
    5.3 Definition von Template-Regeln
    5.4 Anwendung von Template-Regeln
    5.5 Konfliktauflösung bei Template-Regeln
    5.6 Überschreiben von Template-Regeln
    5.7 Modi
    5.8 Eingebaute Template-Regeln
6 Benannte Templates
7 Erzeugung des Ergebnisbaums
    7.1 Erzeugung von Elementen und Attributen
        7.1.1 Literale Ergebniselemente
        7.1.2 Erzeugung von Elementen mit xsl:element
        7.1.3 Erzeugung von Attributen mit xsl:attribute
        7.1.4 Benannte Attributmengen
    7.2 Erzeugung von Text
    7.3 Erzeugung von Verarbeitungsanweisungen
    7.4 Erzeugung von Kommentaren
    7.5 Kopieren
    7.6 Berechnung des erzeugten Texts
        7.6.1 Generierung von Text mit xsl:value-of
        7.6.2 Attributwert-Template
    7.7 Nummerieren
        7.7.1 Attribute für die Umwandlung von Zahlen in Zeichenketten
8 Wiederholung
9 Bedingte Verarbeitung
    9.1 Bedingte Verarbeitung mit xsl:if
    9.2 Bedingte Verarbeitung mit xsl:choose
10 Sortierung
11 Variablen und Parameter
    11.1 Ergebnisbaum-Fragmente
    11.2 Variablen- und Parameterwerte
    11.3 Benutzen von Variablen- und Parameterwerten mit xsl:copy-of
    11.4 Variablen und Parameter auf der obersten Ebene
    11.5 Variablen und Parameter innerhalb von Templates
    11.6 Parameterübergabe an Templates
12 Zusätzliche Funktionen
    12.1 Mehrere Quelldokumente
    12.2 Schlüssel
    12.3 Zahlenformatierung
    12.4 Diverse zusätzliche Funktionen
13 Nachrichten
14 Erweiterungen
    14.1 Erweiterungselemente
    14.2 Erweiterungsfunktionen
15 Rückgriff
16 Ausgabe
    16.1 XML-Ausgabemethode
    16.2 HTML-Ausgabemethode
    16.3 Text-Ausgabemethode
    16.4 Deaktivierung des Ausgabe-Zeichenschutzes
17 Konformität
18 Notation

Anhänge

A Referenzen
    A.1 Normative Referenzen
    A.2 Weitere Referenzen
B Zusammenfassung der Element Syntax
C DTD-Fragment für XSLT Stylesheets (Nicht normativ)
D Beispiele (Nicht normativ)
    D.1 Dokumentbeispiel
    D.2 Datenbeispiel
E Anerkennungen (Nicht normativ)
F Änderungen seit der vorgeschlagenen Empfehlung (Nicht normativ)
G In Erwägung gezogene Fähigkeiten für zukünftige XSLT-Versionen (Nicht normativ)


1 Einführung

Diese Spezifikation definiert die Syntax und Semantik der Sprache XSLT. Eine Transformation in der XSLT-Sprache drückt sich in einem wohlgeformten XML-Dokument [XML] aus, das konform zur »Namensräume in XML«-Empfehlung [XML Names] ist und sowohl Elemente, die durch XSLT definiert sind, und Elemente, die nicht durch XSLT definiert sind, enthalten kann. [Definition: Durch XSLT definierte Elemente sind dadurch ausgezeichnet, dass sie zu einem spezifischen XML-Namensraum gehören (siehe 2.1 XSLT-Namensraum), der in dieser Spezifikation als XSLT-Namensraum bezeichnet wird.] Folglich ist diese Spezifikation eine Definition der Syntax und der Semantik des XSLT-Namensraums.

Eine in XSLT ausgedrückte Transformation beschreibt Regeln für die Transformation eines Quellbaums in einen Ergebnisbaum. Diese Transformation wird durch die Assoziation von Mustern mit Templates erreicht. Ein Muster wird gegen Elemente des Quellbaumes getestet. Ein Template wird instanziiert, um einen Teil des Ergebnisbaumes zu erstellen. Der Ergebnisbaum ist unabhängig vom Quellbaum. Die Struktur des Ergebnisbaums kann sich von der Struktur des Quellbaums komplett unterscheiden. Bei der Konstruktion des Ergebnisbaums können Elemente des Quellbaumes gefiltert und umgeordnet sowie beliebige Struktur hinzugefügt werden.

Eine in XSLT ausgedrückte Transformation wird ein Stylesheet genannt, da die Transformation im Fall der Transformierung von XSLT in das XSL-Formatierungsvokabular als Stylesheet fungiert.

Dieses Dokument spezifiziert nicht, wie ein XSLT-Stylesheet mit einem XML-Dokument assoziiert wird. Es wird empfohlen, dass XSL-Prozessoren den in [XML Stylesheet] beschriebenen Mechanismus unterstützen. Wenn dieser oder irgendein anderer Mechanismus eine Folge von mehr als einem XSLT-Stylesheet einbringt und diese Stylesheets gleichzeitig auf ein XML-Dokument angewendet werden sollen, so soll der Effekt der gleiche sein, als ob ein einzelnes Stylesheet angewendet wird, das jedes Mitglied der Folge der Reihe nach importiert (siehe 2.6.2 Stylesheet-Import).

Ein Stylesheet enthält eine Menge von Template-Regeln. Eine Template-Regel besteht aus zwei Teilen: einem Muster, welches gegen Knoten im Quellbaum geparst wird, und einem Template, welches instanziiert werden kann, um einen Teil des Zielbaums zu formen. Dies erlaubt die Anwendung eines Stylesheets auf eine große Klasse von Dokumenten, die gleichartige Quellbaum-Strukturen haben.

Ein Template wird für ein bestimmtes Quellelement instanziiert, um einen Teil des Ergebnisbaums zu erstellen. Ein Template kann Elemente enthalten, die eine literale Ergebniselement-Struktur spezifizieren. Ein Template kann des Weiteren Elemente aus dem XSLT-Namensraum enthalten, die Anweisungen für die Erstellung von Ergebnisbaum-Fragmenten sind. Wenn ein Template instanziiert wird, wird jede Anweisung ausgeführt und durch das von ihr erzeugte Ergebnisbaum-Fragment ersetzt. Anweisungen können untergeordnete Quellelemente selektieren und verarbeiten. Die Verarbeitung eines untergeordneten Elements erzeugt ein Ergebnisbaum-Fragment durch Auffinden der anwendbaren Template-Regel und Instanziieren ihres Templates. Zu beachten ist, dass Elemente nur verarbeitet werden, wenn sie durch die Ausführung einer Anweisung selektiert worden sind. Der Ergebnisbaum wird durch das Auffinden der Template-Regel für den Wurzelknoten und die Instanziierung ihres Templates konstruiert.

Im Prozess des Auffindens der passenden Template-Regel kann mehr als eine Template-Regel ein zutreffendes Muster besitzen, das zu dem gegebenen Element passt. Es wird jedoch immer nur eine Template-Regel angewendet. Die Entscheidungsmethode, welche Template-Regel angewendet wird, ist in 5.5 Konfliktauflösung bei Template-Regeln beschrieben.

Ein einzelnes Template hat beträchtliche Fähigkeiten: Es kann Strukturen von beliebiger Komplexität erzeugen; es kann den Wert von Zeichenketten aus beliebigen Positionen des Quellbaums auslesen; es kann sich wiederholende Strukturen gemäß dem Vorkommen von Elementen im Quellbaum erzeugen. Für einfache Transformationen, bei denen die Struktur des Ergebnisbaums von der Struktur des Quellbaums unabhängig ist, kann ein Stylesheet oftmals aus nur einem einzelnen Template bestehen, welches als Template für den gesamten Ergebnisbaum fungiert. Transformationen von XML-Dokumenten, die Daten repräsentieren, sind oftmals von solchem Typ (siehe D.2 Datenbeispiel). XSLT erlaubt für derartige Stylesheets eine vereinfachte Syntax (siehe 2.3 Literale Ergebniselemente als Stylesheet).

Wenn ein Template instanziiert wird, wird es immer unter Beachtung eines [Definition: aktuellen Knotens ] und einer [Definition: aktuellen Knotenliste ] instanziiert. Der aktuelle Knoten ist immer ein Mitglied der aktuellen Knotenliste. Viele Operationen in XSLT sind relativ zum aktuellen Knoten. Nur einige wenige Anweisungen wechseln die aktuelle Knotenliste oder den aktuellen Knoten (siehe 5 Template-Regeln und 8 Wiederholung); während der Instanziierung einer dieser Anweisungen wechselt die aktuelle Knotenliste zu einer neuen Liste von Knoten und jedes Element dieser neuen Liste wird der Reihe nach zum aktuellen Knoten; nachdem die Instanziierung der Anweisung abgeschlossen ist, werden der aktuelle Knoten und die aktuelle Knotenliste wieder so zurückgesetzt, wie sie vor dem Aufruf der Anweisung waren.

XSLT benutzt die durch [XPath] definierte Ausdruckssprache, um Elemente zur Verarbeitung, zur konditionalen Verarbeitung oder zur Erzeugung von Text auszuwählen.

XSLT sieht zwei »Eingriffsmöglichkeiten« vor, um die Sprache zu erweitern: eine Eingriffsmöglichkeit, um die Menge der in Templates benutzbaren Anweisungselemente zu erweitern, und eine Eingriffsmöglichkeit, um die Menge der in XPath-Ausdrücken verwendbaren Funktionen zu erweitern. Diese Eingriffsmöglichkeiten basieren beide auf XML-Namensräumen. Diese Version von XSLT definiert keinen Mechanismus, um diese Eingriffsmöglichkeiten zu implementieren. Siehe 14 Erweiterungen.

Anmerkung:

Die XSL-Arbeitsgruppe beabsichtigt einen solchen Mechanismus in einer zukünftigen Version dieser Spezifikation oder in einer separaten Spezifikation zu definieren.

Die Elementsyntax-Zusammenfassungsnotation, die zur Beschreibung der Syntax von XSLT-definierten Elementen verwendet wird, ist in 18 Notation beschrieben.

Die MIME-Medientypen text/xml und application/xml [RFC2376] sollten für XSLT-Stylesheets benutzt werden. Es ist möglich, dass zukünftig ein Medientyp ausdrücklich für XSLT-Stylesheets registriert wird; wenn das so ist, wird dieser Medientyp ebenso verwendet werden können.

2 Stylesheet-Struktur

2.1 XSLT-Namensraum

Der XSLT-Namensraum besitzt den URI http://www.w3.org/1999/XSL/Transform.

Anmerkung:

Die 1999 in dem URI gibt das Jahr an, in welchem der URI durch das W3C zugewiesen wurde. Sie gibt nicht etwa die verwendete XSLT-Version an, die durch Attribute angegeben wird (siehe 2.2 Stylesheet-Element und 2.3 Literale Ergebniselemente als Stylesheet).

XSLT-Prozessoren müssen den XML-Namensraum-Mechanismus [XML Names] benutzen, um Elemente und Attribute aus diesem Namensraum zu erkennen. Elemente des XSLT-Namensraums werden nur im Stylesheet, nicht aber im Quelldokument erkannt. Die komplette Liste der XSLT-definierten Elemente ist in B Zusammenfassung der Element Syntax spezifiziert. Hersteller dürfen den XSLT-Namensraum nicht mit zusätzlichen Elementen oder Attributen erweitern. Stattdessen muss jede Erweiterung in einem separaten Namensraum liegen. Jeder Namensraum, der für zusätzliche Anweisungselemente benutzt wird, muss gemäß des Element-Erweiterungs-Mechanismus identifiziert werden, der in 14.1 Erweiterungselemente spezifiziert ist.

Diese Spezifikation benutzt als Präfix xsl:, um Elemente aus dem XSLT-Namensraum zu referenzieren. Jedoch können XSLT-Stylesheets jedes Präfix benutzen, vorausgesetzt, es gibt eine Namensraum-Deklaration, die dieses Präfix an den URI des XSLT-Namensraums bindet.

Ein Element des XSLT-Namensraums kann jedes Attribut haben, das nicht aus dem XSLT-Namensraum ist, vorausgesetzt, dass der erweiterte Name dieses Attributs einen nicht leeren Namensraum-URI hat. Das Vorhandensein eines solchen Attributs darf das Verhalten von XSLT-Elementen und -Funktionen, die in diesem Dokument definiert sind, nicht verändern. Folglich ist es jedem XSLT-Prozessor freigestellt, solche Attribute zu ignorieren; des Weiteren muss er solche Attribute ohne Fehlerausgabe ignorieren, wenn er den Namensraum-URI nicht erkennt. Solche Attribute können zum Beispiel eindeutige Identifikatoren, Optimierungshinweise oder Dokumentationen beinhalten.

Es ist ein Fehler für ein Element des XSLT-Namensraums, Attribute mit erweiterten Namen zu haben, die einen leeren Namensraum-URI haben (z.B. Attribute mit Namen ohne Präfix), ausgenommen sind die Attribute der in diesem Dokument definierten Elemente.

Anmerkung:

Für die Namen der XSLT-Elemente, -Attribute und -Funktionen gelten folgende Konventionen: Namen werden vollständig kleingeschrieben, zur Trennung von Wörtern werden Bindestriche benutzt und Abkürzungen werden nur dann verwendet, wenn sie bereits in der Syntax einer verwandten Sprache wie XML oder HTML vorkommen.

2.2 Stylesheet-Element

<xsl:stylesheet
id = | id
extension-element-prefixes = | tokens
exclude-result-prefixes = | tokens
version = | number
>
<!-- Inhalt: ( , xsl:import* , top-level-elements ) -->
</xsl:stylesheet

<xsl:transform
id = | id
extension-element-prefixes = | tokens
exclude-result-prefixes = | tokens
version = | number
>
<!-- Inhalt: ( , xsl:import* , top-level-elements ) -->
</xsl:transform

Ein Stylesheet wird durch ein xsl:stylesheet-Element in einem XML-Dokument repräsentiert. xsl:transform ist als Synonym für xsl:stylesheet erlaubt.

Ein xsl:stylesheet-Element muss ein version-Attribut besitzen, das die Version von XSLT angibt, die das Stylesheet benötigt. Für diese Version von XSLT sollte der Wert 1.0 sein. Wenn der Wert nicht gleich 1.0 ist, so ist ein vorwärts-kompatibler Verarbeitungsmodus aktiviert (siehe 2.5 Vorwärts-kompatibles Verarbeiten).

Das xsl:stylesheet-Element kann die folgenden Elementtypen beinhalten:

  • xsl:import

  • xsl:include

  • xsl:strip-space

  • xsl:preserve-space

  • xsl:output

  • xsl:key

  • xsl:decimal-format

  • xsl:namespace-alias

  • xsl:attribute-set

  • xsl:variable

  • xsl:param

  • xsl:template

[Definition: Ein als Kind eines xsl:stylesheet-Elements vorkommendes Element wird ein Element der obersten Ebene genannt.]

Dieses Beispiel zeigt die Struktur eines Stylesheets. Punkte (...) zeigen an, wo Attributwerte oder Inhalte weggelassen wurden. Obgleich dieses Beispiel ein Element jedes erlaubten Typs zeigt, können Stylesheets keines oder mehrere dieser Elemente enthalten.

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:import href="..."/>

  <xsl:include href="..."/>

  <xsl:strip-space elements="..."/>
  
  <xsl:preserve-space elements="..."/>

  <xsl:output method="..."/>

  <xsl:key name="..." match="..." use="..."/>

  <xsl:decimal-format name="..."/>

  <xsl:namespace-alias stylesheet-prefix="..." result-prefix="..."/>

  <xsl:attribute-set name="...">
    ...
  </xsl:attribute-set>

  <xsl:variable name="...">...</xsl:variable>

  <xsl:param name="...">...</xsl:param>

  <xsl:template match="...">
    ...
  </xsl:template>

  <xsl:template name="...">
    ...
  </xsl:template>

</xsl:stylesheet>

Die Reihenfolge, in der Kinder des xsl:stylesheet-Elements vorkommen ist mit Ausnahme der xsl:import-Elemente und der Fehlerbehandlung nicht signifikant. Benutzern ist es freigestellt, die Elemente zu ordnen, wie sie es bevorzugen; Werkzeuge zur Erstellung von Stylesheets brauchen keine Kontrolle über die Reihenfolge, in der die Elemente vorkommen, vorzusehen.

Zusätzlich kann das xsl:stylesheet-Element jegliches Element, das nicht im XSLT-Namensraums liegt, unter der Voraussetzung enthalten, dass der erweiterte Name dieses Elements einen nicht leeren Namensraum-URI hat. Das Vorhandensein solcher Elemente der obersten Ebene darf das Verhalten von den in diesem Dokument definierten XSLT-Elementen und -Funktionen nicht verändern; zum Beispiel wäre es für ein solches Element der obersten Ebene nicht gestattet, zu spezifizieren, dass xsl:apply-templates andere Regeln zur Auflösung von Konflikten benutzen soll. Folglich ist es einem XSLT-Prozessor immer freigestellt, solche Elemente auf oberster Ebene zu ignorieren, und er muss ein Element der obersten Ebene ohne Meldung eines Fehlers ignorieren, wenn er den Namensraum-URI nicht erkennt. Solche Elemente können zum Beispiel

  • Informationen, die von erweiterten Elementen oder erweiterten Funktionen benutzt werden (siehe 14 Erweiterungen),

  • Informationen, was mit dem Ergebnis zu machen ist,

  • Informationen, wie der Quellbaum zu behandeln ist,

  • Metadaten über das Stylesheet oder

  • strukturierte Dokumentation für das Stylesheet

vorsehen.

2.3 Literale Ergebniselemente als Stylesheet

Eine vereinfachte Syntax ist für Stylesheets erlaubt, die nur aus einem einzigen Template für den Wurzelknoten bestehen. Das Stylesheet darf aus nur einem literalen Ergebniselement bestehen (siehe 7.1.1 Literale Ergebniselemente). So ein Stylesheet ist äquivalent zu einem Stylesheet mit einem xsl:stylesheet-Element, das eine Template-Regel beinhaltet, die wiederum das literale Ergebniselement enthält; die Template-Regel hat ein Passmuster von /.

Zum Beispiel hat

<html xsl:version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns="http://www.w3.org/TR/xhtml1/strict">
  <head>
    <title>Expense Report Summary</title>
  </head>
  <body>
    <p lang="en">Total Amount: <xsl:value-of select="expense-report/total"/></p>
  </body>
</html>

die gleiche Bedeutung wie

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns="http://www.w3.org/TR/xhtml1/strict">
<xsl:template match="/">
<html>
  <head>
    <title>Expense Report Summary</title>
  </head>
  <body>
    <p lang="en">Total Amount: <xsl:value-of select="expense-report/total"/></p>
  </body>
</html>
</xsl:template>
</xsl:stylesheet>

Ein literales Ergebniselement, welches das Dokumentelement eines Stylesheets ist, muss ein xsl:version-Attribut haben, das die vom Stylesheet benötigte Version identifiziert. Für diese Version von XSLT sollte der Werte 1.0 sein; der Wert muss eine Nummer sein. Andere literale Ergebniselemente können ebenfalls ein xsl:version-Attribut besitzen. Wenn das xsl:version-Attribut nicht gleich 1.0 ist, so ist ein vorwärts-kompatibler Verarbeitungsmodus aktiviert (siehe 2.5 Vorwärts-kompatibles Verarbeiten).

Der erlaubte Inhalt eines als Stylesheet benutzten literalen Ergebniselements unterscheidet sich nicht von dem Inhalt, der erlaubt wäre, wenn es innerhalb eines Stylesheets vorkäme. Demzufolge kann ein als Stylesheet benutztes literales Ergebniselement keine Elemente der obersten Ebene enthalten.

In einigen Situationen besteht die einzige Möglichkeit eines Systems zu erkennen, dass ein XML-Dokument eine Verarbeitung durch einen XSLT-Prozessor benötigt, darin, das XML-Dokument selbst zu untersuchen. Die Verwendung der vereinfachten Syntax erschwert dies.

Anmerkung:

Zum Beispiel könnte eine andere XML-Sprache (AXL) ebenfalls ein axl:version im Dokumentelement benutzen, um anzugeben, dass ein XML-Dokument ein AXL-Dokument war, das eine Verarbeitung durch einen AXL-Prozessor benötigt; wenn ein Dokument sowohl ein axl:version- als auch ein xsl:version-Attribut hätte, wäre es unklar, ob das Dokument von einem XSLT-Prozessor oder von einem AXL-Prozessor verarbeitet werden sollte.

Demzufolge sollte die vereinfachte Syntax nicht für XSLT-Stylesheets verwendet werden, die in derartigen Situationen verwendet werden könnten. Diese Situation kann beispielsweise vorkommen, wenn ein XSLT-Stylesheet als Nachricht mit einem der MIME-Mediatypen text/xml oder application/xml zu einem Empfänger übertragen wird, der anhand des MIME-Mediatyps bestimmen möchte, wie die Nachricht verarbeitet wird.

2.4 Qualifizierte Namen

Der Name eines internen XSLT-Objekts, im Speziellen eines benannten Templates (siehe 6 Benannte Templates), eines Modus (siehe 5.7 Modi), einer Attributmenge (siehe 7.1.4 Benannte Attributmengen), eines Schlüssels (siehe 12.2 Schlüssel), eines Dezimalzahlformats (siehe 12.3 Zahlenformatierung) einer Variablen oder eines Parameters (siehe 11 Variablen und Parameter), wird als QName angegeben. Wenn es ein Präfix hat, wird das Präfix unter Verwendung derjenigen Namensraum-Deklaration zu einer URI-Referenz erweitert, die auf das Attribut wirkt, in dem der Name erscheint. Der erweiterte Name besteht aus einem lokalen Teil des Namens; die – möglicherweise leere – URI-Referenz wird als Name des Objekts verwendet. Der vorgegebene Namensraum wird nicht für Namen ohne Präfix verwendet.

2.5 Vorwärts-kompatibles Verarbeiten

Ein Element aktiviert den vorwärts-kompatiblen Modus für sich selbst, seine Attribute, seine Nachfahren und deren Attribute, wenn es entweder ein xsl:stylesheet-Element ist, dessen version-Attribut nicht gleich 1.0 ist, oder wenn es ein literales Ergebniselement ist, das ein xsl:version-Attribut hat, dessen Wert ungleich 1.0 ist, oder wenn es ein literales Ergebniselement ist, das kein xsl:version-Attribut hat und das das Dokumentelement eines Stylesheets ist, das die vereinfachte Syntax benutzt (siehe 2.3 Literale Ergebniselemente als Stylesheet). Ein literales Ergebniselement, das ein xsl:version-Attribut hat, dessen Wert gleich 1.0 ist, schaltet den vorwärts-kompatiblen Modus für sich selbst, seine Attribute, seine Nachfahren und deren Attribute aus.

Falls ein Element im vorwärts-kompatiblen Modus verarbeitet wird, so gilt:

  • Falls es ein Element der obersten Ebene ist und XSLT 1.0 derartige Elemente nicht als Elemente der obersten Ebene erlaubt, so muss das Element mit seinem Inhalt ignoriert werden;

  • Falls es ein Element innerhalb eines Templates ist und XSLT 1.0 das Vorkommen solcher Elemente in Templates nicht erlaubt, dann muss ein Fehler angezeigt werden, wenn das Element nicht instanziiert ist; falls das Element instanziiert ist, muss XSLT einen Rückgriff für das Element ausführen, wie in 15 Rückgriff spezifiziert;

  • falls das Element ein Attribut hat, welches das Element nach XSLT 1.0 nicht besitzen darf oder falls das Element ein optionales Attribut mit einem Wert hat, den XSLT 1.0 nicht erlaubt, so muss das Attribut ignoriert werden.

Folglich muss jeder XSLT-1.0-Prozessor in der Lage sein, die folgenden Elemente ohne Fehler zu verarbeiten, auch wenn das Stylesheet Elemente aus dem XSLT-Namensraum beinhaltet, die nicht in dieser Spezifkation definiert sind:

<xsl:stylesheet version="1.1"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <xsl:choose>
      <xsl:when test="system-property('xsl:version') >= 1.1">
        <xsl:exciting-new-1.1-feature/>
      </xsl:when>
      <xsl:otherwise>
        <html>
        <head>
          <title>XSLT 1.1 required</title>
        </head>
        <body>
          <p lang="en">Sorry, this stylesheet requires XSLT 1.1.</p>
        </body>
        </html>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

Anmerkung:

Wenn ein Stylesheet entscheidend von einem Element der obersten Ebene abhängt, das von einer Version von XSL nach 1.0 eingeführt wurde, dann kann das Stylesheet ein xsl:message-Element mit terminate="yes" benutzen (siehe 13 Nachrichten), um sicherzustellen, dass XSLT-Prozessoren, die frühere Versionen von XSL implementieren, nicht stillschweigend das Element der obersten Ebene ignorieren. Zum Beispiel:

<xsl:stylesheet version="1.5"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:important-new-1.1-declaration/>

  <xsl:template match="/">
    <xsl:choose>
      <xsl:when test="system-property('xsl:version') &lt; 1.1">
        <xsl:message terminate="yes">
          <xsl:text>Sorry, this stylesheet requires XSLT 1.1.</xsl:text>
        </xsl:message>
      </xsl:when>
      <xsl:otherwise>
        ...
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  ...
</xsl:stylesheet>

Wenn ein in einem Attribut vorkommt, das im vorwärts-kompatiblen Modus verarbeitet wird, dann muss ein XSLT-Prozessor Fehler in dem Ausdruck wie folgt verarbeiten:

  • Wenn ein Ausdruck nicht der Syntax der XPath-Grammatik genügt, darf ein Fehler so lange nicht ausgegeben werden, bis der Ausdruck tatsächlich ausgewertet wird.

  • Wenn der Ausdruck eine Funktion mit einem Namen ohne Präfix aufruft, die nicht Teil der XSLT-Bibliothek ist, dann darf ein Fehler so lange nicht ausgegeben werden, bis die Funktion tatsächlich aufgerufen wird.

  • Wenn der Ausdruck eine Funktion mit einer Anzahl von Argumenten aufruft, die XSLT nicht erlaubt, oder mit Argumenten aus Typen, die XSLT nicht erlaubt, dann darf ein Fehler so lange nicht ausgegeben werden, bis die Funktion aufgerufen wird.

2.6 Kombination von Stylesheets

XSLT unterstützt zwei Mechanismen, um Stylesheets zu kombinieren:

  • einen Inklusionsmechanismus, der es Stylesheets erlaubt, kombiniert zu werden, ohne die Semantik der kombinierten Stylesheets zu verändern, und
  • einen Importmechanismus, der es Stylesheets erlaubt, einander zu überschreiben.

2.6.1 Stylesheet-Inklusion

<!-- Kategorie: top-level-element -->
<xsl:include
href = | uri-reference
/>

Ein XSLT-Stylesheet kann ein anderes XSLT-Stylesheet durch die Benutzung eines xsl:include-Elements inkludieren. Das xsl:include-Element besitzt ein href-Attribut, dessen Wert eine URI-Referenz ist, die das zu inkludierende Stylesheet identifiziert. Ein relativer URI wird relativ zum Basis-URI des xsl:include-Elements (siehe 3.2 Basis-URI) aufgelöst.

Das xsl:include-Element ist nur als Element der obersten Ebene erlaubt.

Die Inklusion arbeitet auf der Ebene des XML-Baums. Die durch den Wert des href-Attributs lokalisierte Ressource wird als XML-Dokument analysiert und die Kinder des xsl:stylesheet-Elements in diesem Dokument ersetzen das xsl:include-Element im inkludierenden Dokument. Die Tatsache, dass die Template-Regeln oder Definitionen inkludiert sind, beeinflusst nicht die Art, wie sie verarbeitet werden.

Das inkludierte Stylesheet kann die in 2.3 Literale Ergebniselemente als Stylesheet beschriebene vereinfachte Syntax benutzen. Das inkludierte Stylesheet wird gleich dem äquivalenten xsl:stylesheet-Element behandelt.

Es ist ein Fehler, wenn ein Stylesheet sich direkt oder indirekt selbst inkludiert.

Anmerkung:

Ein Stylesheet mehrfach zu inkludieren, kann auf Grund doppelter Definitionen Fehler verursachen. Solche mehrfachen Inklusionen sind weniger offensichtlich, wenn sie indirekt sind. Wenn zum Beispiel Stylesheet B Stylesheet A enthält, Stylesheet C enthält Stylesheet A und Stylesheet D enthält sowohl Stylesheet B als auch Stylesheet C, dann wird Stylesheet A zweimal indirekt von Stylesheet D inkludiert. Wenn B, C und A jeweils als unabhängige Stylesheets verwendet werden, so kann der Fehler vermieden werden, indem der Inhalt von B bis auf die Inklusion von A in ein eigenes Stylesheet B' geschrieben und B derart abgeändert wird, dass es nur noch A und B' inkludiert. Ähnlich verfährt man mit C und ändert D dahingehend, dass A, B' und C' inkludiert werden.

2.6.2 Stylesheet-Import

<xsl:import
href = | uri-reference
/>

Ein XSLT-Stylesheet kann ein anderes XSLT-Stylesheet durch Benutzung des xsl:import-Elements importieren. Ein Stylesheet zu importieren ist das Gleiche, wie es zu inkludieren (siehe 2.6.1 Stylesheet-Inklusion), mit der Ausnahme, dass Definitionen und Template-Regeln in dem importierenden Stylesheet Vorrang gegenüber Template-Regeln und Definitionen in dem importierten Stylesheet haben; dies wird nachstehend im Detail beschrieben. Das xsl:import-Element hat ein href-Attribut, dessen Wert eine das zu importierende Stylesheet identifizierende URI-Referenz ist. Ein relativer URI wird relativ zu dem Basis-URI des xsl:import-Elements (siehe 3.2 Basis-URI) aufgelöst.

Das xsl:import-Element ist nur als Element der obersten Ebene erlaubt. Die xsl:import-Kindelemente müssen allen anderen Kindelemente eines xsl:stylesheet-Elements vorausgehen, dies umfasst auch jegliche xsl:include-Kindelemente. Wenn xsl:include benutzt wird, um ein Stylesheet zu inkludieren, wird jedes xsl:import-Element in dem inkludierten Dokument nach oben hinter jedes existierende xsl:import-Element im inkludierenden Dokument geschoben.

Zum Beispiel:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:import href="article.xsl"/>
  <xsl:import href="bigfont.xsl"/>
  <xsl:attribute-set name="note-style">
    <xsl:attribute name="font-style">italic</xsl:attribute>
  </xsl:attribute-set>
</xsl:stylesheet>

[Definition: Die während der Verarbeitung gefundenen xsl:stylesheet-Elemente, die xsl:import-Elemente enthalten, werden behandelt, als ob sie einen Importbaum formen. In dem Importbaum hat jedes xsl:stylesheet-Element für jedes xsl:import, das es beinhaltet, ein Importkind. Alle xsl:include-Elemente werden aufgelöst, bevor der Importbaum konstruiert wird.] [Definition: Ein xsl:stylesheet-Element im Importbaum hat eine geringere Importpriorität als andere xsl:stylesheet-Elemente in dem Importbaum, wenn es bei einem Post-Order-Durchlauf des Importbaums vor diesem besucht werden würde (z.B. ein Durchlauf des Importbaums, in dem ein xsl:stylesheet- Element nach seinen Importkindern besucht wird).] Jede Definition und jede Template-Regel hat eine Importpriorität, die von dem xsl:stylesheet- Element, das diese enthält, abhängig ist.

  • Stylesheet A importiert die Stylesheets B und C in dieser Reihenfolge;

  • Stylesheet B importiert Stylesheet D;

  • Stylesheet C importiert Stylesheet E.

Dann ist die Reihenfolge der Importpriorität (kleinste zuerst) D, B, E, C, A.

Anmerkung:

Da xsl:import-Elemente vor jeglicher Definition oder Template-Regel vorkommen müssen, sammelt eine Implementierung, die importierte Stylesheets in dem Moment verarbeitet, in dem sie auf das xsl:import-Element trifft, Definitionen und Template-Regeln in aufsteigender Importpriorität auf.

Im Allgemeinen hat eine Definition oder eine Template-Regel mit höherer Importpriorität Vorrang gegenüber einer Definition oder einer Template-Regel mit einer niedrigeren Importpriorität. Dies ist im Detail für jede Art von Definition und Template-Regel definiert.

Es ist ein Fehler, wenn sich ein Stylesheet direkt oder indirekt selbst importiert. Außer an diesem Punkt wird der Fall, dass ein Stylesheet mit einem bestimmten URI an mehreren Stellen importiert wird, nicht besonders beachtet. Der Importbaum wird ein separates xsl:stylesheet für jede Stelle haben, an der es importiert wird.

Anmerkung:

Wenn xsl:apply-imports benutzt wird (siehe 5.6 Überschreiben von Template-Regeln), kann das Verhalten unterschiedlich zu dem Verhalten sein, bei dem das Stylesheet nur an der Stelle mit der höchsten Importpriorität importiert wurde.

2.7 Einbettung von Stylesheets

Normalerweise ist ein XSLT-Stylesheet ein komplettes XML-Dokument mit dem xsl:stylesheet-Element als Dokumentelement. Jedoch kann ein XSLT-Stylesheet ebenso in einer anderen Ressource eingebettet sein. Zwei Formen der Einbettung sind möglich:

  • Das XSLT-Stylesheet kann in Textform in einer Nicht-XML-Ressource eingebettet sein, oder
  • das xsl:stylesheet-Element kann in einem XML-Dokument, jedoch nicht als Dokumentelement, vorkommen.

Um die zweite Form der Einbettung zu vereinfachen, ist es dem xsl:stylesheet-Element erlaubt, ein ID-Attribut zu haben, das einen eindeutigen Identifikator spezifiziert.

Anmerkung:

Damit ein solches Attribut mit der XPath-id-Funktion benutzt werden kann, muss es in der DTD tatsächlich als ID deklariert werden.

Das folgende Beispiel zeigt, wie die xml-stylesheet-Verarbeitungsanweisung [XML Stylesheet] benutzt werden kann, um es einem Dokument zu erlauben, sein eigenes Stylesheet zu enthalten. Die URI-Referenz benutzt einen relativen URI mit einem Teilidentifikator, um das xsl:stylesheet-Element zu lokalisieren:

<?xml-stylesheet type="text/xml" href="#style1"?>
<!DOCTYPE doc SYSTEM "doc.dtd">
<doc>
<head>
<xsl:stylesheet id="style1"
                version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:import href="doc.xsl"/>
<xsl:template match="id('foo')">
  <fo:block font-weight="bold"><xsl:apply-templates/></fo:block>
</xsl:template>
<xsl:template match="xsl:stylesheet">
  <!-- ignore -->
</xsl:template>
</xsl:stylesheet>
</head>
<body>
<para id="foo">
...
</para>
</body>
</doc>

Anmerkung:

Ein Stylesheet, das im Dokument eingebettet ist, auf welches es angewandt wird, oder das in ein Stylesheet inkludiert oder importiert werden kann, so dass es eingebettet ist, muss typischerweise eine Template-Regel enthalten, die spezifiziert, dass xsl:stylesheet-Elemente zu ignorieren sind.

3 Datenmodell

Das von XSLT benutzte Datenmodell ist das gleiche, wie das von XPath benutzte, mit den Ergänzungen, die in diesem Abschnitt beschrieben werden. XSLT operiert auf Quell-, Ergebnis- und Stylesheet-Dokumenten und benutzt das gleiche Datenmodell. Zwei beliebige XML-Dokumente, die den gleichen Baum haben, werden von XSLT als gleich angesehen.

Verarbeitungsanweisungen und Kommentare im Stylesheet werden ignoriert: Das Stylesheet wird behandelt, als ob weder Verarbeitungsanweisungs- noch Kommentarknoten im Baum enthalten wären, der das Stylesheet repräsentiert.

3.1 Kinder des Wurzelknotens

Die normalen Restriktionen für Kinder des Wurzelknotens sind für den Ergebnisbaum gelockert. Der Ergebnisbaum kann jede Folge von Knoten als Kinder haben, die für einen Elementknoten möglich wären. Im Besonderen könnte er Textknoten-Kinder haben und eine beliebige Anzahl von Elementknoten-Kindern. Wenn er unter Benutzung der XML-Output-Methode (siehe 16 Ausgabe) geschrieben wird, ist es möglich, dass ein Ergebnisbaum ein nicht wohlgeformtes XML-Dokument ist; jedoch ist er immer ein wohlgeformtes, extern analysiertes Entity.

Wenn der Quellbaum durch Analysieren eines wohlgeformten XML-Dokuments entsteht, erfüllt der Wurzelknoten des Quellbaums automatisch die normalen Restriktionen, keine Textknoten-Kinder und genau ein Element-Kind zu haben. Wenn der Quellbaum in einer anderen Art erstellt wird, zum Beispiel durch die Benutzung des DOM, werden die üblichen Restriktionen sowohl für den Quellbaum als auch für den Ergebnisbaum gelockert.

3.2 Basis-URI

Jeder Knoten hat einen, seinen Basis-URI genannten, assoziierten URI, welcher zum Auflösen der Attributwerte, die relative URIs repräsentieren, in absoluten URIs benutzt wird. Wenn ein Element oder eine Verarbeitungsanweisung in einem externen Entity vorkommt, ist der Basis-URI dieses Elements oder dieser Verarbeitungsanweisung der URI des externen Entity. Anderenfalls ist der Basis-URI der Basis-URI des Dokument-Entity. Der Basis-URI eines Textknotens, eines Kommentarknotens, eines Attributknotens oder eines Namensraumknotens ist der Basis-URI des Vaters dieses Knotens.

3.3 Nicht analysierte Entitys

Der Wurzelknoten hat eine Abbildung, welche den URI für jedes nicht analysierte Entity angibt, das in der DTD deklariert ist. Der URI wird von dem System-Identifikator und dem in der Entity-Deklaration spezifizierten öffentlichen Identifikator generiert. Der XSLT-Prozessor kann den öffentlichen Identifikator anstelle des im System-Identifikator spezifizierten benutzen, um einen URI für das Entity zu generieren. Wenn der XSLT-Prozessor den öffentlichen Identifkator nicht benutzt, um den URI zu generieren, muss er den System-Identifikator benutzen; wenn der System-Identifikator ein relativer URI ist, muss dieser zu einem absoluten URI aufgelöst werden, wobei der URI der Ressource, welche die Entity-Deklaration beinhaltet, als Basis-URI verwendet wird [RFC2396].

3.4 Entfernen von Leerräumen

Nachdem der Baum eines Quelldokuments oder eines Stylesheet-Dokuments konstruiert wurde, werden einige Textknoten entfernt, bevor er anderweitig von XSLT verarbeitet wird. Solange ein Textknoten andere Zeichen außer Leerraumzeichen enthält, wird er nicht entfernt. Das Entfernen des Textknotens entfernt diesen Textknoten aus dem Baum. Der Prozess des Entfernens verwendet als Eingabe eine Menge von Elementnamen, bei denen Leerräume erhalten bleiben müssen. Der Prozess wird sowohl auf das Stylesheet wie auch auf das Quelldokument angewendet, aber die Menge der Elementnamen, bei denen Leerräume erhalten bleiben, wird für beide unterschiedlich bestimmt.

Ein Textknoten ist (Leerraum-)erhaltend, wenn einer der nachfolgenden Punkte zutrifft:

  • Der Elementname des Vaters des Textknotens gehört zu der Menge der Leerraum erhaltenden Elementnamen.

  • Der Textknoten enthält mindestens ein Nicht-Leerraumzeichen. Wie in XML ist ein Leerraumzeichen #x20, #x9, #xD oder #xA.

  • Ein Vorfahre-Element des Textknotens hat ein xml:space-Attribut mit einem Wert preserve und kein näheres Vorfahre-Element hat ein xml:space mit einem Wert default.

Anderenfalls wird der Textknoten entfernt.

Die xml:space-Attribute werden nicht aus dem Baum entfernt.

Anmerkung:

Dies impliziert, dass ein xml:space-Attribut, das in einem literalen Ergebniselement angegeben ist, im Ergebnis enthalten sein wird.

Für Stylesheets besteht die Menge der Leerraum erhaltenden Elemente lediglich aus xsl:text.

<!-- Kategorie: top-level-element -->
<xsl:strip-space
elements = | tokens
/>

<!-- Kategorie: top-level-element -->
<xsl:preserve-space
elements = | tokens
/>

Für Quelldokumente ist die Menge der Leerraum erhaltenden Elemente durch die Elemente der obersten Ebene, xsl:strip-space und xsl:preserve-space, spezifiziert. Jedes dieser Elemente hat ein elements-Attribut, dessen Wert eine durch Leerzeichen getrennte Liste von NameTests ist. Initial enthält die Menge der Leerraum erhaltenden Elemente alle Elementnamen. Wenn ein Elementname einen NameTest in einem xsl:strip-space-Element erfüllt, dann wird er aus der Menge der Leerraum erhaltenden Elementnamen entfernt. Wenn ein Elementname einen NameTest in einem xsl:preserve-space-Element erfüllt, dann wird er zu der Menge der Leerraum erhaltenden Elemente hinzugefügt. Ein Element erfüllt einen NameTest dann und nur dann, wenn der NameTest für das Element als XPath Knotentest wahr wäre. Konflikte zwischen den Tests zu xsl:strip-space- und xsl:preserve-space-Elementen werden in der gleichen Weise wie Konflikte zwischen Template-Regeln (siehe 5.5 Konfliktauflösung bei Template-Regeln) gelöst. Demzufolge ist der maßgebliche Test für einen einzelnen Elementnamen wie folgt festgelegt:

Es ist ein Fehler, wenn dies mehr als einen Treffer übrig lässt. Ein XSLT-Prozessor kann einen Fehler anzeigen; wenn er keinen Fehler anzeigt, muss er fortfahren, indem er unter den verbleibenden Ergebnissen dasjenige auswählt, welches als Letztes im Stylesheet auftritt.

4 Ausdrücke

XSLT benutzt die durch XPath [XPath] definierte Ausdruckssprache. Ausdrücke werden in XSLT zu verschiedenen Zwecken benutzt:

[Definition: Ein Ausdruck muss den XPath-Produktionsregeln genügen.]

Ausdrücke treten als Wert bestimmter Attribute bei durch XSLT definierten Elementen und innerhalb von geschweiften Klammern in Attributwert-Templates auf.

In XSLT erhält ein äußerster Ausdruck (z.B. ein Ausdruck, der nicht Teil eines anderen Ausdrucks ist) seinen Kontext wie folgt:

5 Template-Regeln

5.1 Verarbeitungsmodell

Eine Liste von Quellknoten wird verarbeitet, um ein Ergebnisbaum-Fragement zu erzeugen. Der Ergebnisbaum wird durch Verarbeitung einer Liste, die nur den Wurzelknoten enthält, erzeugt. Eine Liste von Quellknoten wird verarbeitet, indem die Ergebnisbaum-Struktur, die durch das geordnete Verarbeiten jedes Mitglieds der Liste erzeugt wird, aneinander gehängt wird. Ein Knoten wird durch das Auffinden aller Template-Regeln mit einem zu dem Knoten passenden Muster und durch Auswahl der besten Regel unter diesen verarbeitet. Das ausgewählte Template dieser Regel wird dann mit dem Knoten als aktuellem Knoten und der Liste der Quellknoten als aktueller Knotenliste instanziiert. Ein Template enthält typischerweise Anweisungen, die eine zusätzliche Liste von Quellknoten für die Verarbeitung auswählten. Der Prozess der Prüfung, Instanziierung und der Auswahl wird rekursiv fortgesetzt, bis keine neuen Knoten mehr für die Verarbeitung ausgewählt werden.

Implementierungen ist es freigestellt, ein Quelldokument auf eine beliebige Art zu verarbeiten, solange das Resultat erzielt wird, welches auch mit diesem Verarbeitungsmodell erzielt würde.

5.2 Muster

[Definition: Template-Regeln identifizieren die Knoten, auf die sie angewendet werden, durch die Benutzung eines Musters. Genauso wie für Template-Regeln werden Muster zur Nummerierung (siehe 7.7 Nummerieren) und für die Deklaration von Schlüsseln (siehe 12.2 Schlüssel) benutzt. Ein Muster spezifiziert eine Menge von Bedingungen für einem Knoten. Ein Knoten, der diese Bedingungen erfüllt, passt zu dem Muster. Ein Knoten, der die Bedingungen nicht erfüllt, passt nicht zu dem Muster. Die Syntax für Muster ist eine Teilmenge der Syntax für Ausdrücke. Insbesondere Lokalisierungspfade, die bestimmte Restriktionen erfüllen, können als Muster benutzt werden. Ein Ausdruck, der gleichzeitig Muster ist, wird immer zu einem Objekt des Typs node-set ausgewertet. Ein Knoten erfüllt ein Muster, wenn der Knoten ein Element des Ergebnisses der Auswertung dieses Musters als Ausdruck ist, wobei der mögliche Kontext zu berücksichtigen ist; mögliche Kontexte sind diejenigen, deren Kontextknoten der zu prüfende Knoten oder einer seiner Vorfahren ist.]

Hier sind einige Beispiele für Muster:

  • para passt zu jedem para-Element.

  • * passt zu jedem Element.

  • chapter|appendix passt zu jedem chapter-Element und zu jedem appendix-Element.

  • olist/item passt zu jedem item-Element mit einem olist-Vater.

  • appendix//para passt zu jedem para-Element mit einem nachfolgenden appendix-Element.

  • / passt zum Wurzelknoten.

  • text() passt zu jedem Textknoten.

  • processing-instruction() passt zu jeder Verarbeitungsanweisung.

  • node() passt zu jedem Knoten, außer einem Attributknoten und dem Wurzelknoten.

  • id("W11") passt zu dem Element mit der eindeutigen ID W11.

  • para[1] passt zu jedem para-Element, welches das erste para-Kindelement seines Vaters ist.

  • *[position()=1 and self::para] passt zu jedem para-Element, das das erste Kindelement seines Vaters ist.

  • para[last()=1] passt zu jedem para-Element, das das einzige para-Kindelement seines Vaters ist.

  • items/item[position()>1] passt zu jedem item-Element, das einen items-Vater hat und das nicht das erste item-Kind seines Vaters ist.

  • item[position() mod 2 = 1] wäre wahr für jedes item-Element, das ein ungerades item-Kind seines Vaters ist.

  • div[@class="appendix"]//p passt zu jedem p-Element mit einem vorhergehenden div-Vorfahre-Element, das ein class-Attribut mit dem Wert appendix hat.

  • @class passt zu jedem class-Attribut (nicht zu jedem Element, das ein class-Attribut hat).

  • @* passt zu jedem Attribut.

Ein Muster muss die Grammatik für Muster erfüllen. Ein Muster ist eine Menge durch | getrennter Lokalisierungspfad-Muster. Ein Lokalisierungspfad-Muster ist ein Lokalisierungspfad, dessen Schritte nur die child oder attribute-Achse benutzen. Obwohl Muster die descendant-or-self-Achse nicht benutzen dürfen, können Muster den //-Operator ebenso wie den /-Operator benutzen. Lokalisierungspfade können auch mit einem id- oder einem key-Funktionsaufruf mit einem literalen Argument beginnen. Prädikate in einem Muster können beliebige Ausdrücke benutzen, genau wie Prädikate in einem Lokalisierungspfad.

Muster
[1]   Pattern   ::=    LocationPathPattern
| Pattern '|' LocationPathPattern
[2]   LocationPathPattern   ::=   '/' RelativePathPattern?
| IdKeyPattern (('/' | '//') RelativePathPattern)?
| '//'? RelativePathPattern
[3]   IdKeyPattern   ::=   'id' '(' Literal ')'
| 'key' '(' Literal ',' Literal ')'
[4]   RelativePathPattern   ::=    StepPattern
| RelativePathPattern '/' StepPattern
| RelativePathPattern '//' StepPattern
[5]   StepPattern   ::=    ChildOrAttributeAxisSpecifier NodeTest Predicate*
[6]   ChildOrAttributeAxisSpecifier   ::=    AbbreviatedAxisSpecifier
| ('child' | 'attribute') '::'

Ein Muster ist genau dann als zu einem Knoten passend definiert, wenn es einen möglichen Kontext gibt, der Element der resultierenden Knotenmenge ist, wenn das Muster als Ausdruck mit diesem Kontext ausgewertet wird. Wenn ein Knoten geprüft wird, haben die möglichen Kontexte einen Kontextknoten, der der zu prüfende Knoten oder ein Vorfahre dieses Knotens ist, und eine Kontextknotenliste welche nur den Kontextknoten enthält.

Zum Beispiel passt p zu jedem p-Element, da für jedes p – wenn der Ausdruck p mit dem Vater des p-Elements als Kontext ausgewertet wird – die resultierende Knotenmenge genau dieses p- Element als Element enthalten wird.

Anmerkung:

Dies passt sogar zu einem p-Element, welches das Dokumentelement ist, weil die Dokumentwurzel der Vater des Dokumentelements ist.

Obwohl die Semantik der Muster indirekt mit Terminologien der Ausdrucksauswertung spezifiziert ist, ist es leicht, die Bedeutung eines Musters direkt zu verstehen, ohne in den Strukturen der Ausdrucksauswertung zu denken. In einem Muster gibt das Zeichen | Alternativen an. Ein Muster mit einer oder mehreren durch | getrennten Alternativen passt, wenn eine der Alternativen passt. Ein Muster, das aus einer Folge von durch / oder // getrennten StepPatterns besteht, wird von rechts nach links geprüft. Das Muster passt nur, wenn das am weitesten rechts stehende StepPattern passt und ein geeignetes Element auf den Rest des Musters passt; wenn der Separator ein / ist, ist nur der Vater ein geeignetes Element. Ist der Separator ein //, ist jeder Vorfahr ein geeignetes Element. Ein StepPattern, das die child-Achse benutzt, passt, wenn der Knotentest für diesen Knoten wahr und dieser Knoten kein Attributknoten ist. Ein StepPattern, das die attribute-Achse benutzt, passt, wenn der Knotentest für diesen Knoten wahr ist und dieser Knoten ein Attribut-Knoten ist. Wenn [] auftaucht, dann wird die erste PredicateExpr in einem StepPattern mit dem zu prüfenden Knoten als Kontextknoten und den Geschwistern dieses Kontextknotens, die den Knotentest erfüllen, als Kontextknotenliste, ausgewertet, außer der geprüfte Knoten ist ein Attributknoten. In diesem Fall besteht die Kontextknotenliste aus allen Attributen, die den gleichen Vater wie das geprüfte Attribut haben und die den NameTest erfüllen.

Zum Beispiel passt

appendix//ulist/item[position()=1]

genau dann zu einem Knoten, wenn folgende Bedingungen erfüllt sind:

  • Der Knotentest item ist für den Knoten erfüllt und der Knoten ist kein Attribut. Anders ausgedrückt ist der Knoten ein item-Element.

  • Die Auswertung der PredicateExpr position()=1 mit dem Knoten als Kontextknoten und den Geschwistern dieses Knotens, die item-Elemente sind, als Kontextknotenliste ist wahr.

  • Der Knoten hat einen Vater, der zu appendix//ulist passt. Dies ist dann erfüllt, wenn der Vater ein ulist-Element ist, das ein appendix-Vorfahrelement hat.

5.3 Definition von Template-Regeln

<!-- Kategorie: top-level-element -->
<xsl:template
match = | pattern
name = | qname
priority = | number
mode = | qname
>
<!-- Inhalt: ( , xsl:param* , template ) -->
</xsl:template

Eine Template-Regel wird mittels eines xsl:template-Elements spezifiziert. Das match-Attribut ist ein Muster, das den oder die Quellknoten identifiziert, auf welche(n) die Regel angewandt wird. Das match-Attribut wird benötigt, es sei denn, das xsl:template-Element hat ein name-Attribut (siehe 6 Benannte Templates). Es ist ein Fehler, wenn der Wert des match-Attributs eine Variablenreferenz beinhaltet. Der Inhalt des xsl:template-Elements ist das Template, das instanziiert wird, wenn die Template-Regel angewandt wird.

Zum Beispiel kann ein XML-Dokument beinhalten:

This is an <emph>important</emph> point.

Die folgende Template-Regel passt zu emph-Elementen und produziert ein fo:inline-sequence formatting object mit einer font-weight-Eigenschaft bold.

<xsl:template match="emph">
  <fo:inline-sequence font-weight="bold">
    <xsl:apply-templates/>
  </fo:inline-sequence>
</xsl:template>

Anmerkung:

Beispiele in diesem Dokument benutzen das fo:-Präfix für den Namensraum http://www.w3.org/1999/XSL/Format. Dieser ist der in [XSL] definierte Namensraum für die "formatting objects".

Wie nachstehend beschrieben, verarbeitet das xsl:apply-templates-Element die Kinder des Quellelements rekursiv.

5.4 Anwendung von Template-Regeln

<!-- Kategorie: instruction -->
<xsl:apply-templates
select = | node-set-expression
mode = | qname
>
<!-- Inhalt: ( | xsl:sort | xsl:with-param )* -->
</xsl:apply-templates

Dieses Beispiel erstellt einen Block für ein chapter-Element und verarbeitet dann dessen direkte Kinder.

<xsl:template match="chapter">
  <fo:block>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

Bei Nicht-vorhanden-Sein eines select-Attributs verarbeitet die xsl:apply-templates-Instruktion alle Kinder des aktuellen Knotens inklusive der Textknoten. Textknoten jedoch, die wie in 3.4 Entfernen von Leerräumen spezifiziert entfernt wurden, werden nicht verarbeitet. Falls das Entfernen von Leerraumknoten für ein Element nicht aktiviert wurde, werden alle Leerräume im Inhalt des Elements als Text verarbeitet, und folglich zählen Leerräume zwischen Kindelementen bei der Ermittlung der Position eines Kindelements durch die position-Funktion.

Ein select-Attribut kann benutzt werden, um statt aller Kinder nur Knoten zu verarbeiten, die durch einen Ausdruck ausgewählt werden. Der Wert dieses select-Attributs ist ein Ausdruck. Dieser Ausdruck muss zu einer Knotenmenge ausgewertet werden. Die ausgewählte Knotenmenge wird in der Dokumentreihenfolge verarbeitet, es sei denn, es ist eine Sortierungsangabe (siehe 10 Sortierung) vorhanden. Das folgende Beispiel verarbeitet alle author-Kinder der author-group:

<xsl:template match="author-group">
  <fo:inline-sequence>
    <xsl:apply-templates select="author"/>
  </fo:inline-sequence>
</xsl:template>

Das folgende Beispiel verarbeitet alle given-names der authors, die Kinder von author-group sind:

<xsl:template match="author-group">
  <fo:inline-sequence>
    <xsl:apply-templates select="author/given-name"/>
  </fo:inline-sequence>
</xsl:template>

Dieses Beispiel verarbeitet heading-Nachfahrenelemente des book-Elements.

<xsl:template match="book">
  <fo:block>
    <xsl:apply-templates select=".//heading"/>
  </fo:block>
</xsl:template>

Es ist ebenso möglich, Elemente zu verarbeiten, die nicht Nachfahren eines bestimmten Elements sind. Folgendes Beispiel setzt voraus, dass ein department-Element ein group-Kind und employee-Nachfahren hat. Es findet die Abteilung eines Arbeitnehmers und verarbeitet dann die group-Kinder dieses departments.

<xsl:template match="employee">
  <fo:block>
    Employee <xsl:apply-templates select="name"/> belongs to group
    <xsl:apply-templates select="ancestor::department/group"/>
  </fo:block>
</xsl:template>

Mehrere xsl:apply-templates-Elemente können innerhalb eines einzelnen Templates benutzt werden, um eine einfache Umordnung zu realisieren. Das folgende Beispiel erzeugt zwei HTML-Tabellen. Die erste Tabelle ist mit Binnenverkäufen gefüllt, während die zweite Tabelle mit Auslandsverkäufen gefüllt ist.

<xsl:template match="product">
  <table>
    <xsl:apply-templates select="sales/domestic"/>
  </table>
  <table>
    <xsl:apply-templates select="sales/foreign"/>
  </table>
</xsl:template>

Anmerkung:

Es ist möglich, dass es zwei passende Nachfahren gibt, wovon einer Nachfahre des anderen ist. Dieser Fall wird nicht besondere behandelt: Beide Nachfahren werden wie üblich verarbeitet. Zum Beispiel verarbeitet bei dem folgenden Quelldokument

<doc><div><div></div></div></doc>

die Regel

<xsl:template match="doc">
  <xsl:apply-templates select=".//div"/>
</xsl:template>

sowohl das äußere div wie auch das innere div-Element.

Anmerkung:

Üblicherweise wird xsl:apply-templates nur verwendet, um Knoten zu verarbeiten, die Nachfahren des aktuellen Knotens sind. Eine solche Verwendung des xsl:apply-templates kann nicht zu einer nicht terminierenden Verarbeitungsschleife führen. Wenn xsl:apply-templates jedoch verwendet wird, um Elemente zu verarbeiten, die nicht Nachfahren des aktuellen Knotens sind, besteht die Möglichkeit, dass nicht terminierende Schleifen auftreten. Zum Beispiel:

<xsl:template match="foo">
  <xsl:apply-templates select="."/>
</xsl:template>

Implementierungen können in einigen Fällen in der Lage sein, solche Schleifen zu erkennen. Es besteht jedoch weiterhin die Möglichkeit, dass ein Stylesheet in eine nicht terminierende Schleife gerät, die die Implementierung nicht erkennen kann. Dies kann ein "denial of service security"-Risiko darstellen.

5.5 Konfliktauflösung bei Template-Regeln

Es ist für einen Quellknoten möglich, mehr als eine Template-Regel zu erfüllen. Die anzuwendende Template-Regel kann wie folgt ermittelt werden:

  1. Zuerst werden alle passenden Template-Regeln, die eine niedrigere Importpriorität als die passende Template-Regel besitzen oder Regeln mit der höchsten Importpriorität von den Überlegungen ausgeschlossen.

  2. Als Nächstes werden alle passenden Template-Regeln mit niedrigerer Priorität als die passende Template-Regel oder Regeln mit der höchsten Priorität von den Überlegungen ausgeschlossen. Die Priorität einer Template-Regel ist durch das priority-Attribut der Template-Regel spezifiziert. Der Wert muss eine echte Zahl (positiv oder negativ) sein, die zu der Produktion Nummer mit einem optionalen führenden Minuszeichen (-) passt. [Definition: Die vorgegebene Priorität wird wie folgt berechnet:]

    Deswegen haben die gebräuchlichsten Arten von Mustern (ein Muster, das testet, ob ein Knoten einen bestimmten Typ und einen bestimmten erweiterten Namen hat) die Priorität 0. Die nächste weniger spezifische Art von Mustern (ein Muster, das einen Knoten auf einen bestimmten Typ und einen erweiterten Namen mit einem bestimmten Namensraum-URI testet) hat die Priorität -0.25, weniger spezifische Muster als diese (Muster, die Knoten nur auf bestimmte Typen testen) haben die Priorität -0.5. Spezifischere Muster als die allgemein üblichen haben eine Priorität von 0.5.

Es ist ein Fehler, wenn dieses Vorgehen in mehr als einer passenden Template-Regel resultiert. Ein XSLT-Prozessor kann einen Fehler ausgeben. Wenn er keinen Fehler ausgibt, muss er weiterarbeiten, indem er unter den verbleibenden Template-Regeln diejenige auswählt, welche als Letzte im Stylesheet auftrat.

5.6 Überschreiben von Template-Regeln

<!-- Kategorie: instruction -->
<xsl:apply-imports
/>

Eine Template-Regel, die benutzt wird, um eine Template-Regel in einem importierten Stylesheet (siehe 5.5 Konfliktauflösung bei Template-Regeln) zu überschreiben, kann durch Verwenden des xsl:apply-imports-Elements die überschriebene Template-Regel aufrufen.

[Definition: An jedem Punkt der Verarbeitung eines Stylesheets gibt es eine aktuelle Template-Regel. Jedes Mal, wenn eine Template-Regel durch ein passendes Muster ausgewählt wird, wird diese Template-Regel die aktuelle Template-Regel für die Instanziierung des Templates dieser Regel. Wenn ein xsl:for-each-Element instanziiert wird, bleibt die aktuelle Template-Regel für die Instanziierung des Inhalts des xsl:for-each-Elements leer.]

xsl:apply-imports verarbeitet den aktuellen Knoten nur mit den Template-Regeln, die in das Stylesheet-Element importiert worden sind, das die aktuelle Template-Regel enthält. Es ist ein Fehler, wenn xsl:apply-imports instanziiert wird, während die aktuelle Template-Regel leer ist.

Angenommen, das Stylesheet doc.xsl beinhaltet eine Template-Regel für example-Elemente:

<xsl:template match="example">
  <pre><xsl:apply-templates/></pre>
</xsl:template>

Ein anderes Stylesheet könnte doc.xsl importieren und die Bearbeitung der example-Elemente wie folgt modifizieren:

<xsl:import href="doc.xsl"/>

<xsl:template match="example">
  <div style="border: solid red">
     <xsl:apply-imports/>
  </div>
</xsl:template>

Der kombinierte Effekt wäre, ein example-Element in ein Element der Form

<div style="border: solid red"><pre>...</pre></div>

zu transformieren.

5.7 Modi

Modi erlauben es, ein Element mehrmals zu verarbeiten und jedes Mal ein anderes Ergebnis zu produzieren.

xsl:template und xsl:apply-templates haben beide ein optionales mode-Attribut. Der Wert dieses mode-Attributs ist ein QName, welcher, wie in 2.4 Qualifizierte Namen beschrieben, expandiert wird. Wenn xsl:template kein match-Attribut hat, darf es auch kein mode-Attribut haben. Wenn ein xsl:apply-templates-Element ein mode-Attribut hat, dann wird es nur auf die Template-Regeln der xsl:template-Elemente angewandt, die ein mode-Attribut mit demselben Wert haben; wenn ein xsl:apply-templates-Element kein mode-Attribut hat, dann wird es nur auf die Template-Regeln von xsl:template angewandt, die kein mode-Attribut haben.

5.8 Eingebaute Template-Regeln

Es gibt eine eingebaute Template-Regel, damit eine rekursive Verarbeitung bei Nicht-vorhanden-Sein eines erfolgreichen Mustertests zu einer expliziten Template-Regel in dem Stylesheet fortgesetzt werden kann. Diese Template-Regel wird sowohl auf die Elementknoten, als auch auf den Wurzelknoten angewandt. Folgendes zeigt die Äquivalenz der eingebauten Template-Regel:

<xsl:template match="*|/">
  <xsl:apply-templates/>
</xsl:template>

Des Weiteren gibt es eine eingebaute Template-Regel für jeden Modus, die es erlaubt, die rekursive Verarbeitung bei Nicht-vorhanden-Sein eines erfolgreichen Mustertests zu einer expliziten Template-Regel in dem Stylesheet in dem gleichen Modus fortzusetzen. Diese Template-Regel wird sowohl auf die Elementknoten als auch auf den Wurzelknoten angewandt. Das folgende zeigt die Äquivalenz der eingebauten Template-Regel für den Modus m:

<xsl:template match="*|/" mode="m">
  <xsl:apply-templates mode="m"/>
</xsl:template>

Desweiteren gibt es eine eingebaute Template-Regel für Text- und Attributknoten, die Text direkt kopiert:

<xsl:template match="text()|@*">
  <xsl:value-of select="."/>
</xsl:template>

Die eingebaute Template-Regel für Verarbeitungsanweisungen und Kommentare macht nichts.

<xsl:template match="processing-instruction()|comment()"/>

Die eingebaute Template-Regel für Namensraumknoten macht ebenfalls nichts. Es gibt kein Muster, das durch einen Namensraumknoten erfüllt wird, weswegen die eingebaute Template-Regel die einzige Regel ist, die auf Namensraumknoten angewandt wird.

Die eingebauten Template-Regeln werden verarbeitet, als ob sie implizit vor dem Stylesheet importiert worden wären, und haben daher eine kleinere Importpriorität als alle anderen Template-Regeln. Deshalb kann ein Autor eine eingebaute Template-Regel durch das Inkludieren einer expliziten Template-Regel überschreiben.

6 Benannte Templates

<!-- Kategorie: instruction -->
<xsl:call-template
name = | qname
>
<!-- Inhalt: xsl:with-param* -->
</xsl:call-template

Templates können durch ihren Namen aufgerufen werden. Ein xsl:template-Element mit einem name-Attribut spezifiziert ein benanntes Template. Der Wert dieses name-Attributs ist ein QName, welcher wie in 2.4 Qualifizierte Namen beschrieben erweitert wird. Wenn ein xsl:template-Element ein name-Attribut hat, kann es ebenfalls ein match-Attribut besitzen, muss es aber nicht. Ein xsl:call-template-Element ruft ein Template mittels seines Namens auf; es besitzt ein notwendiges name-Attribut, welches das aufzurufende Template identifiziert. Anders als xsl:apply-templates verändert xsl:call-template den aktuellen Knoten oder die aktuelle Knotenliste nicht.

Die match-, mode- und priority-Attribute in einem xsl:template-Element beeinflussen nicht, ob das Template durch ein xsl:call-template-Element aufgerufen wird. Gleichfalls beeinflusst das name-Attribut in einem xsl:template-Element nicht, ob das Template von einem xsl:apply-templates-Element aufgerufen wird.

Es ist ein Fehler, wenn ein Stylesheet mehr als ein Template mit dem gleichen Namen und der gleichen Importpriorität enthält.

7 Erzeugung des Ergebnisbaums

Dieser Abschnitt beschreibt Anweisungen, die Knoten im Ergebnisbaum direkt erzeugen.

7.1 Erzeugung von Elementen und Attributen

7.1.1 Literale Ergebniselemente

In einem Template wird ein Element, das nicht zum XSLT-Namensraum gehört und das kein Erweiterungselement (siehe 14.1 Erweiterungselemente) ist, instanziiert, um einen Elementknoten mit dem gleichen erweiterten Namen zu erzeugen. Der Inhalt dieses Elements ist ein Template, das instanziiert wird, um den Inhalt für den erzeugten Elementknoten zu erhalten. Der erzeugte Elementknoten wird die Attributknoten erhalten, die bei dem Elementknoten im Stylesheet-Baum vorhanden waren, mit Ausnahme der Attribute mit Namen des XSLT-Namensraums.

Der erzeugte Elementknoten erhält auch eine Kopie der Namensraumknoten, die bei dem Elementknoten im Stylesheet-Baum vorhanden waren, mit Ausnahme jedes Namensraumknotens, dessen String-Wert der XSLT-Namensraum-URI (siehe 14.1 Erweiterungselemente), ein als erweiterter Namensraum deklarierter Namensraum-URI (siehe 14.1 Erweiterungselemente) oder ein als ausgeschlossener Namensraum gekennzeichneter Namensraum-URI ist. Ein Namensraum-URI wird durch die Benutzung eines exclude-result-prefixes-Attributs im xsl:stylesheet-Element oder eines xsl:exclude-result-prefixes-Attributs in einem literalen Ergebniselement als ausgeschlossener Namensraum gekennzeichnet. Der Wert beider Attribute ist eine durch Leerräume getrennte Liste von Namensraum-Präfixen. Der Namensraum, der an jedes dieser Präfixe gebunden ist, wird als ausschließender Namensraum bezeichnet. Es ist ein Fehler, wenn kein Namensraum an ein Präfix des Elements gebunden ist, welches das exclude-result-prefixes- oder das xsl:exclude-result-prefixes-Attribut trägt. Der vorgegebene Namensraum (wie durch xmlns deklariert) kann durch Einbindung von #default in die Liste der Namensraum-Präfixe als ausgeschlossener Namensraum gekennzeichnet werden. Die Kennzeichnung eines Namensraums als ausgeschlossener Namensraum ist in dem Unterbaum des Stylesheets mit dem Element als Wurzel gültig, welches das exclude-result-prefixes- oder das xsl:exclude-result-prefixes-Attribut trägt; ein von einem xsl:stylesheet-Element ausgehender Unterbaum enthält keine Stylesheets, die durch Kinder dieses xsl:stylesheet-Elements importiert oder inkludiert sind.

Anmerkung:

Wenn ein Stylesheet eine Namensraum-Deklaration nur zum Zwecke der Adressierung des Quellbaums benutzt, vermeidet eine Spezifikation des Präfixes im exclude-result-prefixes-Attribut die überflüssige Namensraum-Deklaration im Ergebnisbaum.

Der Wert eines Attributs eines literalen Ergebniselements wird als Attributwert-Template interpretiert: Es kann Ausdrücke in geschweiften Klammern ({}) enthalten.

[Definition: Ein Namensraum-URI im Stylesheet-Baum, der benutzt wird, um einen Namensraum-URI im Ergebnisbaum zu spezifizieren, wird ein literaler Namensraum-URI genannt.] Dies betrifft:

  • den Namensraum-URI im erweiterten Namen des literalen Ergebniselements im Stylesheet,

  • den Namensraum-URI im erweiterten Namen eines Attributs, das für ein literales Ergebniselement im Stylesheet spezifiziert ist,

  • den Zeichenkettenwert eines Namensraumknotens eines literalen Ergebniselements des Stylesheets.

<!-- Kategorie: top-level-element -->
<xsl:namespace-alias
stylesheet-prefix = | prefix | "#default"
result-prefix = | prefix | "#default"
/>

[Definition: Ein Stylesheet kann das xsl:namespace-alias-Element benutzen, um zu deklarieren, dass ein Namensraum-URI ein Alias für einen anderen Namensraum-URI ist.] Wenn ein literaler Namensraum-URI als Alias für einen anderen Namensraum-URI deklariert worden ist, dann wird der Namensraum-URI im Ergebnisbaum anstelle des literalen Namensraum-URI selbst der Namensraum-URIs sein, für den der literale Namensraum-URI ein Alias ist. Das xsl:namespace-alias-Element deklariert, dass der Namensraum-URI, der durch das stylesheet-prefix-Attribut an ein Präfix gebunden wurde, ein Alias für den Namensraum-URI ist, der durch das result-prefix-Attribut an ein Präfix gebunden wurde. Folglich spezifiziert das stylesheet-prefix-Attribut den Namensraum-URI, der im Stylesheet erscheinen wird, und das result-prefix-Attribut spezifiziert den korrespondierenden Namensraum-URI, der im Ergebnisbaum erscheinen wird. Der vorgegebene Namensraum (wie durch xmlns deklariert) kann durch Benutzen von #default anstelle eines Präfixes angegeben werden. Wenn ein Namensraum-URI als Alias für mehrere verschiedene Namensraum-URIs deklariert ist, dann wird die Deklaration mit der höchsten Importpriorität benutzt. Es ist ein Fehler, wenn es mehr als eine solche Deklaration gibt. Ein XSLT-Prozessor kann diesen Fehler anzeigen. Wenn er keinen Fehler anzeigt, muss er weiterarbeiten, indem er unter den Deklarationen mit der höchsten Importpriorität diejenige auswählt, welche als Letzte im Stylesheet vorkommt.

Wenn literale Ergebniselemente benutzt werden, um Element-, Attribut- oder Namensraumknoten zu erzeugen, die den XSLT-Namensraum-URI benutzen, muss das Stylesheet ein Alias verwenden. Zum Beispiel generiert das Stylesheet

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:fo="http://www.w3.org/1999/XSL/Format"
  xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias">

<xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>

<xsl:template match="/">
  <axsl:stylesheet>
    <xsl:apply-templates/>
  </axsl:stylesheet>
</xsl:template>

<xsl:template match="block">
  <axsl:template match="{.}">
     <fo:block><axsl:apply-templates/></fo:block>
  </axsl:template>
</xsl:template>

</xsl:stylesheet>

ein XSLT-Styltsheet aus einem Dokument der Form:

<elements>
<block>p</block>
<block>h1</block>
<block>h2</block>
<block>h3</block>
<block>h4</block>
</elements>

Anmerkung:

Es kann notwendig sein, Aliase auch für andere als den XSLT-Namensraum-URI zu benutzen. Beispielsweise könnten literale Ergebniselemente, die zu einem Namensraum gehören, der digitale Signaturen behandelt, dazu führen, dass XSLT-Stylesheets durch allgemeine Sicherheitssoftware falsch behandelt werden; die Benutzung eines Alias für diesen Namensraum würde die Möglichkeit einer solchen falschen Behandlung vermeiden.

7.1.2 Erzeugung von Elementen mit xsl:element

<!-- Kategorie: instruction -->
<xsl:element
name = { | qname }
namespace = { | uri-reference }
use-attribute-sets = | qnames
>
<!-- Inhalt: template -->
</xsl:element

Das xsl:element-Element erlaubt es, ein Element mit einem berechneten Namen zu erzeugen. Der erweiterte Name des zu erzeugenden Elements ist durch ein notwendiges name-Attribut und ein optionales namespace-Attribut spezifiziert. Der Inhalt des xsl:element-Elements ist ein Template für die Attribute und Kinder des erzeugten Elements.

Das name-Attribut wird als ein Attributwert-Template interpretiert. Es ist ein Fehler, wenn die Zeichenkette, die aus dem Instanziieren des Attributwert-Templates entsteht, kein QName ist. Ein XSLT-Prozessor kann diesen Fehler anzeigen. Wenn er den Fehler nicht anzeigt, muss er weiterarbeiten, indem er die Folge der Knoten, die durch das Instanziieren des Inhalts des xsl:element-Elements entsteht, unter Ausschluss jeglicher initialer Attributknoten als Ergebnis des Instanziierens des xsl:element-Elements liefert. Wenn es kein namespace-Attribut gibt, wird der QName zu einem erweiterten Namen expandiert, indem die Namensraum-Deklarationen verwendet werden, die für das xsl:element-Element gültig sind, inklusive aller vorgegebener Namensraum-Deklarationen.

Wenn das namespace-Attribut vorhanden ist, wird es ebenfalls als ein Attributwert-Template interpretiert. Die Zeichenkette, die durch Instanziieren des Attributwert-Templates entsteht, sollte eine URI-Referenz sein. Es ist kein Fehler, wenn die Zeichenkette keine syntaktisch korrekte URI-Referenz ist. Wenn die Zeichenkette leer ist, dann hat der erweiterte Name des Elements einen leeren Namensraum-URI, andernfalls wird die Zeichenkette als Namensraum-URI des erweiterten Namens des zu erzeugenden Elements benutzt. Der durch das name-Attribut spezifizierte lokale Teil des QName wird als lokaler Teil des erweiterten Namens des zu erzeugenden Elements benutzt.

XSLT-Prozessoren können von dem im name-Attribut spezifizierten Präfix des QName Gebrauch machen, wenn sie das Präfix für die Ausgabe des erzeugten Elements als XML wählen; jedoch sind sie nicht gezwungen, so zu verfahren.

7.1.3 Erzeugung von Attributen mit xsl:attribute

<!-- Kategorie: instruction -->
<xsl:attribute
name = { | qname }
namespace = { | uri-reference }
>
<!-- Inhalt: template -->
</xsl:attribute

Das xsl:attribute-Element kann benutzt werden, um Attribute zu Ergebniselementen hinzuzufügen, egal, ob diese durch literale Ergebniselemente oder Instruktionen wie xsl:element erzeugt wurden. Der erweiterte Name des zu erzeugenden Attributs ist durch ein notwendiges name-Attribut und ein optionales namespace-Attribut spezifiziert. Die Instanziierung eines xsl:attribute-Elements fügt einen Attributknoten zu dem enthaltenden Ergebniselementknoten hinzu. Der Inhalt des xsl:attribute-Elements ist ein Template für den Wert des erzeugten Attributs.

Das name-Attribut wird als Attributwert-Template interpretiert. Es ist ein Fehler, wenn eine Zeichenkette, die aus der Instanziierung des Attibutwert-Templates resultiert, kein QName ist oder wenn die Zeichenkette die Zeichenkette xmlns ist. Ein XSLT-Prozessor kann einen Fehler anzeigen. Wenn er keinen Fehler anzeigt, muss er fortfahren, ohne das Attribut zum Ergebnisbaum hinzuzufügen. Wenn das namespace-Attribut nicht vorhanden ist, wird der QName durch Benutzung der Namensraum-Deklarationen, die in dem xsl:attribute-Element wirken – exklusive irgendwelcher vorgegebener Namensraum-Deklarationen – zu einem erweiterten Namen expandiert.

Wenn das namespace-Attribut vorhanden ist, wird es ebenfalls als Attributwert-Template interpretiert. Die Zeichenkette, die aus der Instanziierung resultiert, sollte eine URI-Referenz sein. Es ist kein Fehler, wenn die Zeichenkette keine syntaktisch korrekte URI-Referenz ist. Wenn die Zeichenkette leer ist, dann hat der erweiterte Name des Attributs einen leeren Namensraum-URI. Anderenfalls wird die Zeichenkette als Namensraum-URI für den erweiterten Namen des zu erzeugenden Attributs benutzt. Der durch das name-Attribut spezifizierte lokale Teil des QName wird als lokaler Teil des erweiterten Namens des zu erzeugenden Attributs benutzt.

XSLT-Prozessoren können von dem im name-Attribut spezifizierten Präfix des QName Gebrauch machen, wenn das Präfix zur Ausgabe des erzeugten Attributs als XML gewählt wird; jedoch müssen sie nicht so verfahren. Ist das Präfix xmlns, dann dürfen sie es nicht. Obwohl es kein Fehler ist, führt folglich

<xsl:attribute name="xmlns:xsl" namespace="whatever">http://www.w3.org/1999/XSL/Transform</xsl:attribute>

nicht zur Ausgabe einer Namensraum-Deklaration.

Das Hinzufügen eines Attributs zu einem Element ersetzt jedes existierende Attribut dieses Elements mit dem gleichen erweiterten Namen.

Folgendes sind Fehler:

  • Hinzufügen eines Attributs zu einem Element, nachdem Kinder hinzugefügt worden sind; Implementierungen können entweder einen Fehler anzeigen oder das Attribut ignorieren.

  • Hinzufügen eines Attributs zu einem Knoten, der kein Element ist; Implementierungen können entweder einen Fehler anzeigen oder das Attribut ignorieren.

  • Erzeugung von anderen Knoten außer Textknoten während der Instanziierung des Inhalts des xsl:attribute-Elements; Implementierungen können entweder einen Fehler anzeigen oder die betreffenden Knoten ignorieren.

Anmerkung:

Wenn ein xsl:attribute einen Textknoten mit einem Zeilenumbruch enthält, dann muss die XML-Ausgabe eine Zeichenreferenz enthalten. Zum Beispiel führt

<xsl:attribute name="a">x
y</xsl:attribute>

zu der Ausgabe

a="x&#xA;y"

(oder mit irgendeiner äquivalenten Zeichenreferenz). Die XML-Ausgabe kann nicht

a="x
y"

sein.

Dies ist so, weil XML 1.0 erzwingt, dass Zeilenumbruchszeichen in Attributwerten zu Leerräumen normalisiert werden, aber auch erzwingt, dass Zeichenreferenzen auf Zeilenumbrüche nicht normalisiert werden. Die Attributwerte im Datenmodell repräsentieren die Attributwerte nach der Normalisierung. Wenn ein Zeilenumbruch in einem Attributwert im Baum als ein Zeilenumbruch ausgegeben werden würde und nicht als Zeichenreferenz, enthielte der Attributwert im Baum, der durch erneutes Einlesen des XML entstünde, nur noch ein Leerzeichen und keinen Zeilenumbruch, was bedeuten würde, dass der Baum nicht korrekt ausgegeben wurde.

7.1.4 Benannte Attributmengen

<!-- Kategorie: top-level-element -->
<xsl:attribute-set
name = | qname
use-attribute-sets = | qnames
>
<!-- Inhalt: xsl:attribute* -->
</xsl:attribute-set

Das xsl:attribute-set-Element definiert eine benannte Menge von Attributen. Das name-Attribut spezifiziert den Namen der Attributmenge. Der Wert des name-Attributs ist ein QName, welcher wie in 2.4 Qualifizierte Namen beschrieben erweitert wird. Der Inhalt des xsl:attribute-set-Elements besteht aus keinem oder mehreren xsl:attribute-Elementen, welche die Attribute der Menge spezifizieren.

Attributmengen werden durch Spezifizieren eines use-attribute-sets-Attributs bei einem xsl:element-, xsl:copy- (siehe 7.5 Kopieren) oder xsl:attribute-set-Elements benutzt. Der Wert des use-attribute-sets-Attributs ist eine durch Leerräume getrennte Liste von Namen der Attributmengen. Jeder Name ist als QName spezifiziert, welcher wie in 2.4 Qualifizierte Namen beschrieben erweitert wird. Das Spezifizieren eines use-attribute-sets-Attributs entspricht dem Hinzufügen von xsl:attribute-Elementen für jedes Attribut in den benannten Attributmengen, und zwar zu Beginn des Inhalts des Elements mit dem use-attribute-sets-Attribut und in der Reihenfolge, in der die Namen der Attributmengen im use-attribute-sets-Attribut angegeben sind. Es ist ein Fehler, wenn der Gebrauch von use-attribute-sets-Attributen bei xsl:attribute-set-Elementen dazu führt, dass eine Attributmenge sich direkt oder indirekt selbst benutzt.

Attributmengen können auch durch die Spezifizierung eines xsl:use-attribute-sets-Attributs auf einem literalen Ergebniselement benutzt werden. Der Wert des xsl:use-attribute-sets ist eine durch Leerräume getrennte Liste von Namen der Attributmengen. Das xsl:use-attribute-sets-Attribut hat den gleichen Effekt wie das use-attribute-sets-Attribut bei xsl:element mit der zusätzlichen Regel, dass auf dem literalen Ergebniselement spezifizierte Attribute behandelt werden, als ob sie durch xsl:attribute-Elemente vor jedem echten xsl:attribute-Element, aber nach jedem durch das xsl:use-attribute-sets-Attribut implizierten xsl:attribute-Element spezifiziert wurden. Deswegen werden einem literalen Ergebniselement zuerst Attribute aus einer in einem xsl:use-attribute-sets-Attribut genannten Attributmenge in der Reihenfolge, in der sie in dem Attribut aufgelistet sind, hinzugefügt, danach Attribute, die auf dem literalen Ergebniselement spezifiziert sind, und schliesslich wird jedes durch xsl:attribute-Elemente spezifizierte Attribut hinzugefügt. Weil das Hinzufügen eines Attributs zu einem Element jedes bestehende Attribut dieses Elements mit dem gleichen Namen ersetzt, bedeutet dies, dass in Attributmengen spezifizierte Attribute von Attributen, die auf dem literalen Ergebniselement spezifiziert sind, überschrieben werden können.

Das Template innerhalb jedes xsl:attribute-Elements in einem xsl:attribute-set-Element wird jedes Mal, wenn die Attributmenge benutzt wird, instanziiert. Es wird unter Benutzung des gleichen aktuellen Knotens und der gleichen aktuellen Knotenliste instanziiert, die für die Instanziierung des Elements, dass das use-attribute-sets- oder das xsl:use-attribute-sets-Attribut trägt, benutzt werden. Dennoch bestimmt die Position des xsl:attribute-Elements innerhalb des Stylesheets und nicht die des Elements, welches das use-attribute-sets- oder xsl:use-attribute-sets-Attribut trägt, welche Variablenbindungen sichtbar sind (siehe 11 Variablen und Parameter). Aus diesem Grund sind nur Variablen und Parameter, die auf oberster Ebene durch xsl:variable- und xsl:param-Elemente deklariert wurden, sichtbar.

Das folgende Beispiel erzeugt eine benannte Attributmenge title-style und benutzt sie in einer Template-Regel.

<xsl:template match="chapter/heading">
  <fo:block quadding="start" xsl:use-attribute-sets="title-style">
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<xsl:attribute-set name="title-style">
  <xsl:attribute name="font-size">12pt</xsl:attribute>
  <xsl:attribute name="font-weight">bold</xsl:attribute>
</xsl:attribute-set>

Mehrere Definitionen einer Attributmenge mit dem gleichen erweiterten Namen werden verschmolzen. Ein Attribut einer Definition, das eine höhere Importpriorität hat, hat Vorrang vor einem Attribut aus einer Definition, die eine niedrigere Importpriorität besitzt. Es ist ein Fehler, wenn zwei Attributmengen den gleichen erweiterten Namen und die gleiche Importpriorität haben und beide das gleiche Attribut enthalten, außer es gibt eine Definition dieser Attributmenge mit einer höheren Importpriorität, die ebenfalls das Attribut beinhaltet. Ein XSLT-Prozessor kann einen Fehler anzeigen. Wenn er keinen Fehler anzeigt, muss er fortfahren, indem er unter den Definitionen, die das Attribut spezifizieren und die die höchsten Importpriorität haben, diejenige auswählt, welche als Letzte im Stylesheet spezifiziert wurde. Wo die Attribute in einer Attributmenge spezifiziert wurden, ist nur für das Verschmelzen der Attribute in der Attributmenge relevant; es macht keinen Unterschied in der Verwendung der Attributmenge.

7.2 Erzeugung von Text

Ein Template kann auch Textknoten enthalten. Jeder Textknoten, der nach Entfernung der Leerzeichen wie in 3.4 Entfernen von Leerräumen spezifiziert übrig bleibt, erzeugt einen Textknoten mit dem gleichen Zeichenkettenwert im Ergebnisbaum. Benachbarte Textknoten werden im Ergebnisbaum automatisch verschmolzen.

Es ist zu beachten, dass Text auf Baumebene verarbeitet wird. Deshalb wird eine Auszeichnung &lt; in einem Template im Stylesheet-Baum als ein Textknoten, der das Zeichen < enthält, repräsentiert. Dies wird, wenn der Ergebnisbaum in ein XML-Dokument geschrieben wird, einen Textknoten im Ergebnisbaum erzeugen, der ein <-Zeichen enthält, welches durch die Auszeichnung &lt; (oder eine äquivalente Zeichenreferenz) repräsentiert wird. (Es sei denn der Ausgabe-Zeichenschutz (escaping) ist, wie in 16.4 Deaktivierung des Ausgabe-Zeichenschutzes) beschrieben, ausgeschaltet).

<!-- Kategorie: instruction -->
<xsl:text
disable-output-escaping = | "yes" | "no"
>
<!-- Inhalt: #PCDATA -->
</xsl:text

Literale Datenzeichen können ebenfalls in einem xsl:text-Element eingeschlossen werden. Dieses Einschließen kann beeinflussen, wie Leerraumzeichen entfernt werden (siehe 3.4 Entfernen von Leerräumen), aber es beeinflusst nicht, wie die Zeichen danach von einem XSLT-Prozessor benutzt werden.

Anmerkung:

Die xml:lang- und xml:space-Attribute werden durch XSLT nicht besonders behandelt. Im Besonderen

  • liegt es in der Verantwortung des Stylesheet-Autors, jedes xml:lang- oder xml:space-Attribut, das im Ergebnis benötigt wird, zu generieren;

  • führt Spezifizieren eines xml:lang- oder xml:space-Attributs auf einem Element im XSLT-Namensraum nicht dazu, dass irgendein xml:lang oder xml:space-Attribut im Ergebnis erscheint.

7.3 Erzeugung von Verarbeitungsanweisungen

<!-- Kategorie: instruction -->
<xsl:processing-instruction
name = { | ncname }
>
<!-- Inhalt: template -->
</xsl:processing-instruction

Das xsl:processing-instruction-Element wird instanziiert, um einen Verarbeitungsanweisungsknoten zu erzeugen. Der Inhalt des xsl:processing-instruction-Elements ist ein Template für den Zeichenkettenwert des Verarbeitungsanweisungsknotens. Das xsl:processing-instruction-Element hat ein notwendiges name-Attribut, das den Namen des Verarbeitungsanweisungsknotens spezifiziert. Der Wert des name-Attributs wird als ein Attributwert-Template interpretiert.

Zum Beispiel würde

<xsl:processing-instruction name="xml-stylesheet">
 href="book.css" type="text/css"
</xsl:processing-instruction>

die folgende Verarbeitungsanweisung erzeugen:

<?xml-stylesheet href="book.css" type="text/css"?>

Es ist ein Fehler, wenn die Zeichenkette, die aus der Instanziierung des name-Attributs resultiert, nicht sowohl ein NCName als auch ein PITarget ist. Ein XSLT-Prozessor kann einen Fehler anzeigen. Wenn er keinen Fehler anzeigt, muss er fortfahren, ohne die Verarbeitungsanweisung dem Ergebnisbaum hinzuzufügen.

Anmerkung:

Dies bedeutet, dass xsl:processing-instruction nicht benutzt werden kann, um eine XML-Deklaration auszugeben. Stattdessen sollte das xsl:output-Element (siehe 16 Ausgabe) benutzt werden.

Es ist ein Fehler, wenn das Instanziieren des Inhalts von xsl:processing-instruction andere Knoten als Textknoten erzeugt. Ein XSLT-Prozessor kann einen Fehler ausgeben. Wenn er keinen Fehler ausgibt, muss er fortfahren, indem er die fehlerhaften Knoten mitsamt ihrem Inhalt ignoriert.

Es ist ein Fehler, wenn das Ergebnis der Instanziierung des Inhalts einer xsl:processing-instruction die Zeichenkette ?> enthält. Ein XSLT-Prozessor kann einen Fehler ausgeben. Wenn er keinen Fehler ausgibt, muss er fortfahren, indem er ein Leerzeichen nach jedem Vorkommen von ?, dem ein > folgt, einfügt.

7.4 Erzeugung von Kommentaren

<!-- Kategorie: instruction -->
<xsl:comment
>
<!-- Inhalt: template -->
</xsl:comment

Das xsl:comment-Element wird instanziiert, um einen Kommentarknoten im Ergebnisbaum zu erzeugen. Der Inhalt des xsl:comment-Elements ist ein Template für den Zeichenkettenwert des Kommentarknotens.

Zum Beispiel würde

<xsl:comment>This file is automatically generated. Do not edit!</xsl:comment>

den folgenden Kommentar erzeugen

<!--This file is automatically generated. 
                      Do not edit!-->

Es ist ein Fehler, wenn das Instanziieren des Inhalts von xsl:comment andere Knoten als Textknoten erzeugt. Ein XSLT-Prozessor kann einen Fehler ausgeben. Wenn er keinen Fehler ausgibt, muss er fortfahren, indem er die fehlerhaften Knoten mitsamt ihrem Inhalt ignoriert.

Es ist ein Fehler, wenn das Ergebnis der Instanziierung des Inhalt eines xsl:comment die Zeichenkette -- enthält oder mit - endet. Ein XSLT-Prozessor kann einen Fehler ausgeben. Wenn er keinen Fehler ausgibt, muss er fortfahren, indem er ein Leerzeichen nach jedem Vorkommen von -, dem ein - folgt oder das den Kommentar beendet, einfügt.

7.5 Kopieren

<!-- Kategorie: instruction -->
<xsl:copy
use-attribute-sets = | qnames
>
<!-- Inhalt: template -->
</xsl:copy

Das xsl:copy-Element bietet einen einfachen Weg, um den aktuellen Knoten zu kopieren. Das Instanziieren des xsl:copy-Elements erzeugt eine Kopie des aktuellen Knotens. Die Namensraumknoten des aktuellen Knotens werden ebenfalls automatisch kopiert, die Attribute und die Kinder des Knotens hingegen werden nicht automatisch kopiert. Der Inhalt des xsl:copy-Elements ist ein Template für die Attribute und Kinder des erzeugten Knotens; der Inhalt wird nur für Knoten von dem Typ instanziiert, die Attribute oder Kinder haben können (z.B. Wurzelknoten oder Elementknoten).

Das xsl:copy-Element kann ein use-attribute-sets-Attribut (siehe 7.1.4 Benannte Attributmengen) haben. Dieses wird nur benutzt, wenn Elementknoten kopiert werden.

Der Wurzelknoten wird besonders behandelt, weil der Wurzelknoten des Ergebnisbaums implizit erzeugt wird. Wenn der aktuelle Knoten der Wurzelknoten ist, wird xsl:copy keinen Wurzelknoten erzeugen, sondern bloß das Inhalts-Template verwenden.

Zum Beispiel kann die Identitätstransformation durch die Benutzung von xsl:copy wie folgt geschrieben werden:

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

Wenn der aktuelle Knoten ein Attribut ist, dann wäre es ein Fehler, xsl:attribute zu benutzen, um ein Attribut mit dem gleichen Namen wie der aktuelle Knoten zu erzeugen, und es ist dann ebenfalls ein Fehler, xsl:copy (siehe 7.1.3 Erzeugung von Attributen mit xsl:attribute ) zu benutzen.

Das folgende Beispiel zeigt, wie xml:lang-Attribute leicht von der Eingabe zum Ergebnis kopiert werden können. Wenn ein Stylesheet das folgende benannte Template definiert:

<xsl:template name="apply-templates-copy-lang">
 <xsl:for-each select="@xml:lang">
   <xsl:copy/>
 </xsl:for-each>
 <xsl:apply-templates/>
</xsl:template>

kann es leicht

<xsl:call-template name="apply-templates-copy-lang"/>

anstelle von

<xsl:apply-templates/>

benutzen, wenn es das xml:lang-Attribut kopieren möchte.

7.6 Berechnung des erzeugten Texts

Innerhalb eines Templates kann das xsl:value-of-Element benutzt werden, um Text zu berechnen, zum Beispiel durch Extrahieren von Text aus dem Quellbaum oder durch Einfügen des Wertes einer Variablen. Das xsl:value-of-Element macht dies mittels eines Ausdrucks, der als Wert des select-Attributs spezifiziert ist. Ausdrücke können auch innerhalb von Attributwerten eines literalen Ergebniselements durch Umschließen des Ausdrucks mit geschweiften Klammern ({}) benutzt werden.

7.6.1 Generierung von Text mit xsl:value-of

<!-- Kategorie: instruction -->
<xsl:value-of
select = | string-expression
disable-output-escaping = | "yes" | "no"
/>

Das xsl:value-of-Element wird instanziiert, um einen Textknoten im Ergebnisbaum zu erzeugen. Das notwendige select-Attribut ist ein Ausdruck. Dieser Ausdruck wird evaluiert und das resultierende Objekt wird durch einen Aufruf der string-Funktion in eine Zeichenkette konvertiert. Die Zeichenkette spezifiziert den Zeichenkettenwert des erzeugten Textknotens. Wenn die Zeichenkette leer ist, wird kein Textknoten erzeugt. Der erzeugte Textknoten wird mit jedem benachbarten Textknoten verschmolzen.

Das xsl:copy-of-Element kann benutzt werden, um eine Knotenmenge in den Ergebnisbaum zu kopieren, ohne diese in eine Zeichenkette zu konvertieren. Siehe 11.3 Benutzen von Variablen- und Parameterwerten mit xsl:copy-of .

So erzeugt das nachstehende Beispiel einen HTML-Absatz aus einem person-Element mit given-name- und family-name-Attributen. Der Absatz wird den Wert des given-name-Attributs des aktuellen Knotens, gefolgt von einem Leerzeichen und dem Wert des family-name-Attributs des aktuellen Knoten enthalten.

<xsl:template match="person">
  <p lang="en">
   <xsl:value-of select="@given-name"/>
   <xsl:text> </xsl:text>
   <xsl:value-of select="@family-name"/>
  </p>
</xsl:template>

Als ein anderes Beispiel erzeugt das folgende Stylesheet einen HTML-Absatz aus einem person-Element mit given-name und family-name-Kindelementen. Der Absatz wird den Zeichenkettenwert des ersten given-name-Kindelements des aktuellen Knotens, gefolgt von einem Leerzeichen und dem Zeichenkettenwert des ersten family-name-Kindelements des aktuellen Knotens enthalten.

<xsl:template match="person">
  <p lang="en">
   <xsl:value-of select="given-name"/>
   <xsl:text> </xsl:text>
   <xsl:value-of select="family-name"/>
  </p>
</xsl:template>

Das folgende Stylesheet stellt jedem procedure-Element einen Absatz voran, der die Sicherheitsstufe der Prozedur enthält. Es setzt voraus, dass die Sicherheitsstufe, die für eine Prozedur gilt, durch ein security-Attribut des procedure-Elements oder auf einem Vorfahre-Element dieser Prozedur bestimmt ist. Es setzt ebenfalls voraus, dass die Sicherheitsstufe von dem Element bestimmt wird, welches am nächsten an der Prozedur steht, wenn mehr als ein solches Element ein security-Attribut besitzt.

<xsl:template match="procedure">
  <fo:block>
    <xsl:value-of select="ancestor-or-self::*[@security][1]/@security"/>
  </fo:block>
  <xsl:apply-templates/>
</xsl:template>

7.6.2 Attributwert-Template

[Definition: In einem Attributwert, der als ein Attributwert-Template interpretiert wird, wie beispielsweise ein Attribut eines literalen Ergebniselements, kann ein Ausdruck durch Umschließen des Ausdrucks mit geschweiften Klammern ({}) verwendet werden]. Das Attributwert-Template wird durch Ersetzen des Ausdrucks inklusive der geschweiften Klammern durch das Ergebnis der Auswertung des Ausdrucks und Konvertieren des Ergebnisobjekts in eine Zeichenkette – wie durch die string-Funktion – instanziiert. Geschweifte Klammern werden innerhalb eines Attributwerts nicht weiter beachtet, außer für das Attribut ist ausdrücklich festgelegt, dass es als Attributwert-Template interpretiert wird. In einer Elementsyntax-Zusammenfassung ist der Wert solcher Attribute von geschweiften Klammern umgeben.

Anmerkung:

Nicht alle Attribute werden als Attributwert-Templates interpretiert. Attribute, deren Werte ein Ausdruck oder ein Muster sind, Attribute von Elementen der obersten Ebene und Attribute, die sich auf benannte XSLT-Objekte beziehen, werden nicht als Attributwert-Templates interpretiert. Ergänzend hierzu werden xmlns-Attribute nicht als Attributwert-Templates interpretiert; es wäre nicht konform zur XML-Namensraum-Empfehlung, dies zu tun.

Das folgende Beispiel erstellt ein img-Ergebniselement aus einem photograph-Element in der Eingabe; der Wert des src-Attributs des img-Elements wird aus dem Wert der image-dir-Variablen und dem Zeichenkettenwert des href-Kinds des photograph-Elements berechnet; der Wert des width-Attributs des img-Elements wird aus dem Wert des width-Attributs des size-Kinds des photograph-Elements berechnet:

<xsl:variable name="image-dir">/images</xsl:variable>

<xsl:template match="photograph">
<img src="{$image-dir}/{href}" width="{size/@width}"/>
</xsl:template>

Mit dieser Eingabe

<photograph>
  <href>headquarters.jpg</href>
  <size width="300"/>
</photograph>

wäre das Ergebnis:

<img src="/images/headquarters.jpg" width="300"/>

Wenn ein Attributwert-Template instanziiert wird, wird eine doppelte linke oder rechte geschweifte Klammer außerhalb des Ausdrucks durch eine einzelne geschweifte Klammer ersetzt. Es ist ein Fehler, wenn eine rechte geschweifte Klammer in einem Attributwert-Template außerhalb eines Ausdrucks auftritt, ohne von einer zweiten rechten geschweiften Klammer gefolgt zu werden. Eine rechte geschweifte Klammer innerhalb eines Literals innerhalb eines Ausdrucks wird nicht als den Ausdruck beendend erkannt.

Geschweifte Klammer werden innerhalb eines Ausdrucks nicht rekursiv erkannt. Zum Beispiel ist

<a href="#{id({@ref})/title}">

nicht erlaubt. Stattdessen verwendet man einfach:

<a href="#{id(@ref)/title}">

7.7 Nummerieren

<!-- Kategorie: instruction -->
<xsl:number
level = | "single" | "multiple" | "any"
count = | pattern
from = | pattern
value = | number-expression
format = { | string }
lang = { | nmtoken }
letter-value = { | "alphabetic" | "traditional" }
grouping-separator = { | char }
grouping-size = { | number }
/>

Das xsl:number-Element wird benutzt, um eine formatierte Zahl in den Ergebnisbaum einzufügen. Die Zahl, die eingefügt werden soll, kann durch einen Ausdruck spezifiziert sein. Das value-Attribut beinhaltet einen Ausdruck. Der Ausdruck wird ausgewertet und das resultierende Objekt wird wie durch einen Aufruf der number-Funktion in eine Zahl konvertiert. Die Zahl wird zu einer ganzen Zahl gerundet und dann unter Benutzung der in 7.7.1 Attribute für die Umwandlung von Zahlen in Zeichenketten spezifizierten Attribute in eine Zeichenkette konvertiert; in diesem Kontext wird der Wert jedes dieser Attribute als Attributwert-Template interpretiert. Nach der Umwandlung wird die resultierende Zeichenkette in den Ergebnisbaum eingefügt.

Das folgende Beispiel nummeriert eine sortierte Liste:

<xsl:template match="items">
  <xsl:for-each select="item">
    <xsl:sort select="."/>
    <p lang="en">
      <xsl:number value="position()" format="1. "/>
      <xsl:value-of select="."/>
    </p>
  </xsl:for-each>
</xsl:template>

Wenn kein value-Attribut spezifiziert ist, fügt das xsl:number-Element eine Zahl ein, die auf der Position des aktuellen Knotens im Quellbaum basiert. Die folgenden Attribute kontrollieren, wie der aktuelle Knoten zu nummerieren ist:

  • Das level-Attribut spezifiziert, welche Ebenen des Quellbaums beachtet werden sollen; es hat den Wert single, multiple oder any. Die Voreinstellung ist single.

  • Das count-Attribut ist ein Muster, das spezifiziert, welche Knoten auf diesen Ebenen gezählt werden sollen. Wenn das count-Attribut nicht spezifizizert ist, wird das Muster, das auf jeden Knoten mit dem gleichen Knoten wie der aktuelle Knoten passt und, wenn der aktuelle Knoten einen erweiterten Namen hat, mit dem gleichen erweiterten Namen wie der aktuelle Knoten, voreingestellt.

  • Das from-Attribut ist ein Muster, das spezifiziert, wo das Zählen beginnt.

Ergänzend hierzu werden die in 7.7.1 Attribute für die Umwandlung von Zahlen in Zeichenketten spezifizierten Attribute zur Umwandlung von Zahlen in Zeichenketten benutzt, genauso wie in dem Fall, dass das value-Attribut spezifiziert ist.

Das xsl:number-Element konstruiert unter Benutzung der level-, count- und from-Attribute als Erstes eine Liste von positiven ganzen Zahlen:

  • Wenn level="single" ist, geht es aufwärts zum ersten Knoten auf der ancestor-or-self-Achse, der zu dem count-Muster passt, und konstruiert eine Liste der Länge eins, die eine 1 + Anzahl der vorausgehenden Brüder dieses Vorfahrens enthält, die das count-Muster erfüllen. Wenn es keinen solchen Vorfahr gibt, konstruiert es eine leere Liste. Wenn das from-Attribut spezifiziert ist, dann sind die einzigen Vorfahren, in denen gesucht wird, die, die Nachfahren des nächsten Vorfahrens sind, der das from-Muster erfüllt. »Vorausgehende Brüder« hat an dieser Stelle die gleiche Bedeutung wie die preceding-sibling-Achse.

  • Wenn level="multiple" ist, erstellt es eine Liste aller Vorfahren des aktuellen Knotens in der Reihenfolge ihres Vorkommens im Dokument, gefolgt von dem Element selbst. Dann wählt es aus der Liste alle Knoten aus, die dem count-Muster entsprechen. Danach bildet es jeden Knoten der neuen Liste auf 1 + Anzahl der vorausgehenden Brüder des Knotens ab, die dem count-Muster entsprechen. Wenn das from-Attribut angegeben ist, werden nur Vorfahren betrachtet, die Nachfahren des nächesten Vorfahrens sind, der dem from-Muster entspricht. »Vorausgehende Brüder« hat an dieser Stelle die gleiche Bedeutung wie die preceding-sibling-Achse.

  • Wenn level="any" ist, erstellt es eine Liste der Länge 1, die die Anzahl der Knoten enthält, die dem count-Muster entsprechen und der Menge aus dem aktuellen Knoten und aller Knoten auf jeder Ebene des Dokuments angehören, die in der Dokumentreihenfolge vor dem aktuellen Knoten liegen und keine Namensraum- oder Attributknoten sind (in anderen Worten: der Vereinigung der Elemente der preceding- und ancestor-or-self-Achsen). Wenn das from-Attribut angegeben ist, werden nur Knoten nach dem ersten Knoten vor dem aktuellen Knoten, die dem from-Muster entsprechen, berücksichtigt.

Die Liste der Zahlen wird dann in eine Zeichenkette konvertiert, dabei werden die in 7.7.1 Attribute für die Umwandlung von Zahlen in Zeichenketten spezifizierten Attribute verwendet. In diesem Kontext wird der Wert eines jeden dieser Attribute als Attributwert-Template interpretiert. Nach der Umwandlung wird die resultierende Zeichenkette in den Ergebnisbaum eingefügt.

Das folgende Stylesheet würde die Elemente in einer geordneten Liste nummerieren:

<xsl:template match="ol/item">
  <fo:block>
    <xsl:number/><xsl:text>. </xsl:text><xsl:apply-templates/>
  </fo:block>
<xsl:template>

Die folgenden zwei Regeln würden title-Elemente nummerieren. Dies ist für ein Dokument gedacht, das eine Reihe von Kapiteln, gefolgt von einer Reihe von Anhängen, enthält, in dem sowohl die Kapitel als auch die Anhänge Abschnitte enthalten, die wiederum Unterabschnitte enthalten. Kapitel sind mit 1, 2, 3 nummeriert; Anhänge sind mit A, B, C nummeriert; Abschnitte in Kapiteln sind mit 1.1, 1.2, 1.3 nummeriert; Abschnitte in Anhängen sind mit A.1, A.2, A.3 nummeriert.

<xsl:template match="title">
  <fo:block>
     <xsl:number level="multiple"
                 count="chapter|section|subsection"
                 format="1.1 "/>
     <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<xsl:template match="appendix//title" priority="1">
  <fo:block>
     <xsl:number level="multiple"
                 count="appendix|section|subsection"
                 format="A.1 "/>
     <xsl:apply-templates/>
  </fo:block>
</xsl:template>

Das folgende Beispiel nummeriert Anmerkungen in einem Kapitel sequenziell:

<xsl:template match="note">
  <fo:block>
     <xsl:number level="any" from="chapter" format="(1) "/>
     <xsl:apply-templates/>
  </fo:block>
</xsl:template>

Das folgende Beispiel würde H4-Elemente in HTML mit einem dreiteiligen Label nummerieren:

<xsl:template match="H4">
 <fo:block>
   <xsl:number level="any" from="H1" count="H2"/>
   <xsl:text>.</xsl:text>
   <xsl:number level="any" from="H2" count="H3"/>
   <xsl:text>.</xsl:text>
   <xsl:number level="any" from="H3" count="H4"/>
   <xsl:text> </xsl:text>
   <xsl:apply-templates/>
 </fo:block>
</xsl:template>

7.7.1 Attribute für die Umwandlung von Zahlen in Zeichenketten

Die folgenden Attribute werden benutzt, um die Umwandlung einer Reihe von Zahlen in eine Zeichenkette zu kontrollieren. Die Zahlen sind ganze Zahlen größer als 0. Die Attribute sind alle optional.

Das Hauptattribut ist format. Der voreingestellte Wert für das format-Attribut ist 1. Das format-Attribut ist in eine Reihe von Token aufgesplittet, wobei jedes Token eine maximale Sequenz von alphanumerischen Zeichen oder eine maximale Sequenz von nicht alphanumerischen Zeichen ist. Alphanumerisch meint jedes Zeichen, das eine Unicode-Kategorie von Nd, Nl, No, Lu, Ll, Lt, Lm oder Lo besitzt. Die alphanumerischen Token (Format-Token) spezifizieren das für jede Zahl in der Liste zu benutzende Format. Wenn das erste Token ein nicht alphanumerisches Token ist, so wird die konstruierte Zeichenkette mit diesem Token beginnen; wenn das letzte Token ein nicht alphanumerisches Token ist, so wird die Zeichenkette mit diesem Token enden. Nicht alphanumerische Token, die zwischen zwei Format-Token erscheinen, sind Separator-Token, die benutzt werden, um Zahlen an die Liste anzuhängen. Das nte Format-Token wird benutzt, um die nte Zahl in der Liste zu formatieren. Wenn es mehr Zahlen als Format-Token gibt, so wird das letzte Format-Token benutzt, um alle verbleibenden Zahlen zu formatieren. Wenn es keine Format-Token gibt, so wird das Format-Token 1 benutzt, um alle Zahlen zu formatieren. Das Format-Token spezifiziert die Zeichenkette, die zu benutzen ist, um die Zahl 1 zu repräsentieren. Jede Zahl nach der ersten wird von der vorausgehenden Zahl durch ein, dem zum Formatieren dieser Zahl benutzten Format-Token vorausgehenden, Separator-Token oder, wenn es keine Separator-Token gibt, durch einen . (ein Gruppierungszeichen) getrennt.

Format-Token sind eine Obermenge der erlaubten Werte für das type-Attribut des OL-Elements in HTML 4.0 und werden wie folgt interpretiert:

  • Jedes Token, bei dem das letzte Zeichen einen Dezimalzifferwert von 1 (wie in der Unicode character property database spezifiziert) hat und der Unicode-Wert vorausgehender Zeichen eins weniger als der Unicode-Wert des letzen Zeichen ist, generiert eine Dezimalzahlrepräsentation dieser Zahl, wobei jede Zahl mindestens so lang ist wie das Format-Token. Deshalb generiert ein Format-Token 1 die Sequenz 1 2 ... 10 11 12 ... und ein Format-Token 01 generiert die Sequenz 01 02 ... 09 10 11 12 ... 99 100 101.

  • Ein Format-Token A generiert die Sequenz A B C ... Z AA AB AC....

  • Ein Format-Token a generiert die Sequenz a b c ... z aa ab ac....

  • Ein Format-Token i generiert die Sequenz i ii iii iv v vi vii viii ix x ....

  • Ein Format-Token I generiert die Sequenz I II III IV V VI VII VIII IX X ....

  • Jedes andere Format-Token zeigt eine Aufzählung an, die mit diesem Token beginnt. Wenn eine Implementierung keine Aufzählung unterstützt, die mit diesem Token beginnt, muss sie das Format-Token 1 benutzen.

Wenn mit einer alphabetischen Reihe nummeriert wird, spezifiziert das lang-Attribut die Sprache, deren Alphabet zu benutzen ist; es hat den gleichen Wertebereich wie xml:lang [XML]; wenn kein lang-Wert spezifiziert ist, sollte die Sprache aus der Systemumgebung bestimmt werden. Implementierer sollten dokumentieren, für welche Sprachen sie Nummerierung unterstützen.

Anmerkung:

Implementierer sollten keine Annahmen darüber machen, wie Nummerierung in bestimmten Sprachen funktioniert, und sie sollten die Sprachen, die sie unterstützen möchten, sauber erforschen. Die Aufzählungsvereinbarungen vieler Sprachen sind im Vergleich zum Englischen sehr verschieden.

Das letter-value-Attribut macht die Aufzählungen, die Buchstaben benutzen, eindeutig. In vielen Sprachen gibt es zwei allgemein benutzte Aufzählungen, die Buchstaben benutzen. Eine Aufzählung weist nummerischen Werten Buchstaben in alphabetischer Reihenfolge zu, und die andere weist Buchstaben nummerische Werte auf eine andere, in dieser Sprache traditionelle, Art zu. Im Englischen würde dies Aufzählungen mit den Format-Token a und i entsprechen. In einigen anderen Sprachen ist das erste Mitglied einer jeden Sequenz das Gleiche und so wäre das Format-Token alleine zweideutig. Ein Wert von alphabetic spezifiziert die alphabetische Reihenfolge; Ein Wert von traditional spezifiziert die andere Reihenfolge. Wenn das letter-value-Attribut nicht spezifiziert ist, dann ist es implementierungsabhängig, wie Unklarheiten aufgelöst werden.

Anmerkung:

Es ist für zwei XSLT-Prozessoren möglich, eine Zahl nicht in die exakt gleiche Zeichenkette zu konvertieren. Einige XSLT-Prozessoren könnten einige Sprachen nicht unterstützen. Darüber hinaus mag es Variationsmöglichkeiten in der Art geben, wie Umwandlungen für eine bestimmte Sprache, die nicht durch die Attribute von xsl:number spezifizierbar ist, ausgeführt werden. Zukünftige Versionen von XSLT könnten zusätzliche Attribute vorsehen, um eine Kontrolle über diese Variationen zu erhalten. Ebenfalls könnten Implementierungen hierfür Implementations-spezifische Attribute mit Namensräumen für xsl:number benutzen.

Das grouping-separator-Attribut gibt den als Gruppierungs-Separator (z.B. Tausender) benutzen Separator an und das optionale grouping-size spezifiziert die Größe (normalerweise 3) für diese Gruppierung. Zum Beispiel würde grouping-separator="," und grouping-size="3" Zahlen der Form 1,000,000 produzieren. Wenn nur eines der grouping-separator- und grouping-size-Attribute spezifiziert ist, wird es ignoriert.

Hier sind einige Beispiele für Umwandlungsspezifikationen:

  • format="&#x30A2;" spezifiziert Katakana-Nummerierung.

  • format="&#x30A4;" spezifiziert Katakana-Nummerierung in der "iroha"-Ordnung.

  • format="&#x0E51;" spezifiziert Nummerierung mit thailändischen Ziffern.

  • format="&#x05D0;" letter-value="traditional" spezifiziert "traditionelle" hebräische Nummerierung.

  • format="&#x10D0;" letter-value="traditional" spezifiziert georgische Nummerierung.

  • format="&#x03B1;" letter-value="traditional" spezifiziert »klassische« griechische Nummerierung.

  • format="&#x0430;" letter-value="traditional" spezifiziert alt-slawische Nummerierung.

8 Wiederholung

<!-- Kategorie: Anweisung -->
<xsl:for-each
select = | node-set-expression
>
<!-- Inhalt: ( , xsl:sort* , template ) -->
</xsl:for-each

Falls ein Ergebnis eine bekannte reguläre Struktur hat, kann es nützlich sein, ein Template für die ausgewählten Knoten direkt angeben zu können. Die xsl:for-each-Anweisung enthält ein Template, das für jeden Knoten instanziiert wird, der durch den Ausdruck des select-Attributs ausgewählt wird. Das select-Attribut ist notwendig. Der Ausdruck muss eine Knotenmenge zurückliefern. Das Template wird mit dem ausgewählten Knoten als aktuellem Knoten und mit einer Liste aller ausgewählten Knoten als aktueller Knotenliste instanziiert. Die Knoten werden in der Reihenfolge ihres Auftretens im Dokument abgearbeitet, es sei denn, eine Sortierangabe ist vorhanden (siehe 10 Sortierung).

Als Beispiel sei ein XML-Dokument mit folgender Struktur gegeben:

<customers>
  <customer>
    <name>...</name>
    <order>...</order>
    <order>...</order>
  </customer>
  <customer>
    <name>...</name>
    <order>...</order>
    <order>...</order>
  </customer>
</customers>

Folgendes würde ein HTML-Dokument erzeugen, das eine Tabelle mit einer Spalte für jedes customer-Element enthält:

<xsl:template match="/">
  <html>
    <head>
      <title>Customers</title>
    </head>
    <body>
      <table>
	<tbody>
	  <xsl:for-each select="customers/customer">
	    <tr>
	      <th>
		<xsl:apply-templates select="name"/>
	      </th>
	      <xsl:for-each select="order">
		<td>
		  <xsl:apply-templates/>
		</td>
	      </xsl:for-each>
	    </tr>
	  </xsl:for-each>
	</tbody>
      </table>
    </body>
  </html>
</xsl:template>

9 Bedingte Verarbeitung

Es gibt zwei Anweisungen in XSLT, die eine bedingte Verarbeitung in einem Template ermöglichen: xsl:if und xsl:choose. Die xsl:if-Anweisung ermöglicht einfache Wenn-dann-Bedingungen; die xsl:choose-Anweisung ermöglicht die Selektion einer Auswahl, falls mehrere Möglichkeiten bestehen.

9.1 Bedingte Verarbeitung mit xsl:if

<!-- Kategorie: Anweisung -->
<xsl:if
test = | boolean-expression
>
<!-- Inhalt: Template -->
</xsl:if

Das xsl:if-Element besitzt ein test-Attribut, welches einen Ausdruck angibt. Der Inhalt ist ein Template. Der Ausdruck wird ausgewertet und das Ergebnisobjekt in ein Boolean gewandelt, equivalent zum Aufruf der boolean-Funktion. Falls das Ergebnis wahr ist, wird der Inhalt des Templates instanziiert, ansonsten wird nichts erzeugt. Im folgenden Beispiel werden Namen in einer Gruppe von Namen als eine durch Komma separierte Liste formatiert:

<xsl:template match="namelist/name">
  <xsl:apply-templates/>
  <xsl:if test="not(position()=last())">, </xsl:if>
</xsl:template>

Folgendes Beispiel färbt jede zweite Tabellenspalte gelb:

<xsl:template match="item">
  <tr>
    <xsl:if test="position() mod 2 = 0">
       <xsl:attribute name="bgcolor">yellow</xsl:attribute>
    </xsl:if>
    <xsl:apply-templates/>
  </tr>
</xsl:template>

9.2 Bedingte Verarbeitung mit xsl:choose

<!-- Kategorie: Anweisung -->
<xsl:choose
>
<!-- Inhalt: ( , xsl:when+ , xsl:otherwise? ) -->
</xsl:choose

<xsl:when
test = | boolean-expression
>
<!-- Inhalt: Template -->
</xsl:when

<xsl:otherwise
>
<!-- Inhalt: Template -->
</xsl:otherwise

Das xsl:choose-Element wählt aus einer Menge von Möglichkeiten eine aus. Es besteht aus einer Abfolge von xsl:when-Elementen, gefolgt von einem optionalen xsl:otherwise-Element. Jedes xsl:when-Element besitzt das Attribut test, das einen Ausdruck angibt. Der Inhalt der xsl:when- und xsl:otherwise-Elemente ist jeweils ein Template. Bei der Verarbeitung des xsl:choose-Elements werden alle xsl:when-Elemente der Reihe nach getestet, indem der Ausdruck ausgewertet und das Ergebnisobjekt in ein Boolean gewandelt wird, equivalent zum Aufruf der boolean-Funktion. Instanziiert wird der Inhalt des ersten (und nur des ersten) xsl:when-Elements, dessen Test wahr ist. Falls keines der xsl:when-Elemente wahr ist, wird der Inhalt des xsl:otherwise-Elements instanziiert. Falls kein xsl:when-Element wahr ist und kein xsl:otherwise-Element vorhanden ist, wird nichts erzeugt.

Im folgenden Beispiel werden Elemente einer geordneten Liste mit arabischen Ziffern, Buchstaben oder römischen Zahlen, abhängig von der Tiefe der Listenverschachtelung, nummeriert.

<xsl:template match="orderedlist/listitem">
  <fo:list-item indent-start='2pi'>
    <fo:list-item-label>
      <xsl:variable name="level"
                    select="count(ancestor::orderedlist) mod 3"/>
      <xsl:choose>
        <xsl:when test='$level=1'>
          <xsl:number format="i"/>
        </xsl:when>
        <xsl:when test='$level=2'>
          <xsl:number format="a"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:number format="1"/>
        </xsl:otherwise>
      </xsl:choose>
      <xsl:text>. </xsl:text>
    </fo:list-item-label>
    <fo:list-item-body>
      <xsl:apply-templates/>
    </fo:list-item-body>
  </fo:list-item>
</xsl:template>

10 Sortierung

<xsl:sort
select = | string-expression
lang = { | nmtoken }
data-type = { | "text" | "number" | qname-but-not-ncname }
order = { | "ascending" | "descending" }
case-order = { | "upper-first" | "lower-first" }
/>

Eine Sortierung kann durch Hinzufügen von xsl:sort-Elementen als Kinder eines xsl:apply-templates- oder xsl:apply-templates-Elements spezifiziert werden. Das erste xsl:sort-Kind spezifiziert den primären Sortierschlüssel, das zweite xsl:sort-Kind gibt den sekundären Sortierschlüssel an und so weiter. Wenn ein xsl:apply-templates- oder xsl:for-each-Element mehr als ein xsl:sort-Kind besitzt, werden die gewählten Knoten nicht in Dokumentreihenfolge verarbeitet, sondern die Knoten entsprechend der spezifizierten Sortierschlüssel sortiert und in sortierter Reihenfolge verarbeitet. Bei Benutzung in xsl:for-each müssen xsl:sort-Elemente zuerst auftreten. Falls ein Template durch xsl:apply-templates und xsl:for-each instanziiert wird, besteht die Liste der aktuellen Knotenlisten aus der kompletten Liste der Knoten, die verarbeitet werden, in sortierter Reihenfolge.

xsl:sort besitzt ein select-Attribut, dessen Wert ein Ausdruck ist. Bei jedem zu verarbeitenden Knoten wird der Ausdruck mit dem Knoten als aktuellem Knoten und mit der kompletten Liste der zu verarbeitenden Knoten in unsortierter Reihenfolge als aktueller Knotenliste ausgewertet. Das resultierende Objekt wird, wie bei einem Aufruf der string-Funktion, zu einer Zeichenkette umgewandelt; diese Zeichenkette wird als Sortierschlüssel für diesen Knoten verwendet. Der Standardwert des select-Attributs ist ein ., was die Verwendung des Zeichenkettenwerts des aktuellen Knotens als Sortierschlüssel bedingt.

Diese Zeichenkette dient als Sortierschlüssel für den Knoten. Die folgenden optionalen Attribute für xsl:sort kontrollieren, wie die Liste der Sortierschlüssel sortiert wird; die Werte all dieser Attribute werden als Attributwert-Templates interpretiert.

Anmerkung:

Es besteht die Möglichkeit, dass zwei konforme XSLT-Prozessoren nicht exakt gleich sortieren. Einige XSLT-Prozessoren könnten einige Sprachen nicht unterstützen. Des Weiteren können Abweichungen bei der Sortierung in einer speziellen Sprache existieren, die nicht durch die Attribute von xsl:sort angegeben werden, zum Beispiel, ob Hiragana oder Katakana im Japanischen zuerst sortiert wird. Zukünftige Versionen von XSLT könnten zusätzliche Attribute besitzen, um diese Abweichungen zu kontrollieren. Implementierungen können auch implementierungs-spezifische Attribute mit Namensräumen mit xsl:sort zu diesem Zweck verwenden.

Anmerkung:

Es wird empfohlen, dass Implementierer [UNICODE TR10] für Informationen bzgl. internationalisiertem Sortieren zu Rate ziehen.

Die Sortierung muss stabil sein: Jede Teilliste in der sortierten Liste der Knoten, deren Sortierschlüssel im Vergleich equivalent sind, muss in Dokument-Ordnung vorkommen.

Zum Beispiel werde eine Angestellten-Datenbank folgender Form angenommen:

<employees>
  <employee>
    <name>
      <given>James</given>
      <family>Clark</family>
    </name>
    ...
  </employee>
</employees>

Eine nach Namen sortierte Liste der Angestellten könnte wie folgt generiert werden:

<xsl:template match="employees">
  <ulist>
    <xsl:apply-templates select="employee">
      <xsl:sort select="name/family"/>
      <xsl:sort select="name/given"/>
    </xsl:apply-templates>
  </ulist>
</xsl:template>

<xsl:template match="employee">
  <item>
    <xsl:value-of select="name/given"/>
    <xsl:text> </xsl:text>
    <xsl:value-of select="name/family"/>
  </item>
</xsl:template>

11 Variablen und Parameter

<!-- Kategorie: top-level-element -->
<!-- Kategorie: instruction -->
<xsl:variable
name = | qname
select = | expression
>
<!-- Inhalt: template -->
</xsl:variable

<!-- Kategorie: top-level-element -->
<xsl:param
name = | qname
select = | expression
>
<!-- Inhalt: template -->
</xsl:param

Eine Variable besteht aus einem Namen, der an einen Wert gebunden ist. Der Wert, an den eine Variable gebunden ist (der Wert der Variablen), kann ein Objekt jener Typen sein, die von Ausdrücken zurückgeliefert werden können. Es gibt zwei Elemente, die genutzt werden können, um Variablen einzubinden: xsl:variable und xsl:param. Der Unterschied liegt darin, dass der in der xsl:param-Variablen angegebene Wert nur ein Vorgabewert für die Bindung ist; wenn ein Template oder Stylesheet aufgerufen wird, innerhalb dessen ein xsl:param-Element vorkommt, können Parameter übergeben werden, die anstelle des Vorgabewertes benutzt werden.

Beide, xsl:variable und xsl:param, besitzen ein benötigtes name-Attribut, welches den Namen der Variablen festlegt. Der Wert des name-Attributs ist ein QName, der wie in 2.4 Qualifizierte Namen beschrieben expandiert wird.

Bei jeder Benutzung dieser Variablen-Bindungs-Elemente gibt es einen Bereich des Stylesheets-Baums, in dem die Bindung sichtbar ist; innerhalb dieses Bereichs wird jede Bindung der Variablen unsichtbar, die im Variablen-Bindungs-Element selbst sichtbar war. Folglich ist nur die innerste Bindung einer Variablen sichtbar. Die Menge der Variablenbindungen im Kontext eines Ausdrucks besteht aus genau den Bindungen, die an jenem Punkt im Stylesheet sichtbar sind, an dem der Ausdruck verwendet wird.

11.1 Ergebnisbaum-Fragmente

Variablen ergänzen die Ausdruckssprache um einen zusätzlichen Datentyp. [Definition: Dieser zusätzliche Datentyp wird Ergebnisbaum-Fragment genannt. Eine Variable kann statt einem der vier XPath Basis-Datentypen (string, number, boolean, node-set) an ein Ergebnisbaum-Fragment gebunden werden. Ein Ergebnisbaum-Fragment ist ein Teil des Ergebnisbaums. Ein Ergebnisbaum-Fragment wird equivalent zu einer Knotenmenge mit nur einem Wurzelknoten behandelt.] Jedoch sind die auf einem Ergebnisbaum-Fragment möglichen Operationen eine Untermenge der möglichen Operationen auf einer Knotenmenge. Eine Operation ist auf einem Ergebnisbaum-Fragment nur dann möglich, wenn die Anwendung dieser Operation auf einer Zeichenkette möglich wäre (die Operation auf der Zeichenkette darf zuerst eine Umwandlung der Zeichenkette in eine Zahl oder ein Boolean beinhalten). Insbesondere ist es nicht möglich, die /-, //- und []-Operatoren auf das Ergebnisbaum-Fragment anzuwenden. Wenn eine mögliche Operation auf ein Ergebnisbaum-Fragment angewandt wird, wird die Operation exakt so durchgeführt, wie sie bei der equivalenten Knotenmenge durchgeführt worden wäre.

Wenn ein Ergebnisbaum-Fragment in den Ergebnisbaum kopiert wird (siehe 11.3 Benutzen von Variablen- und Parameterwerten mit xsl:copy-of ), werden alle Knoten, die Kinder des Wurzelknotens in der equivalenten Knotenmenge sind, sequenziell zum Ergebnisbaum hinzugefügt.

Ausdrücke können nur Rückgabewerte vom Typ Ergebnisbaum-Fragment liefern, indem sie Variablen vom Typ Ergebnisbaum-Fragment referenzieren, oder indem sie Erweiterungsfunktionen aufrufen, die ein Ergebnisbaum-Fragment zurückliefern, oder indem sie eine Systemeigenschaft holen, deren Wert ein Ergebnisbaum-Fragment ist.

11.2 Variablen- und Parameterwerte

Ein variablenbindendes Element kann den Wert einer Variablen auf drei verschiedene Arten angeben:

  • Wenn das variablenbindende Element ein select-Attribut besitzt, dann muss der Wert des Attributs ein Ausdruck sein und der Wert der Variablen ist das Objekt, das aus der Auswertung des Ausdrucks resultiert. In diesem Fall muss der Inhalt leer sein.

  • Wenn das variablenbindende Element kein select-Attribut und einen nicht leeren Inhalt besitzt (z.B. wenn das variablenbindende Element ein oder mehrere Kindknoten hat), dann wird der Wert durch den Inhalt des variablenbindenden Elements angegeben. Der Inhalt des variablenbindenden Elements ist ein Template, welches instanziiert wird, um den Wert der Variablen zurückzugeben. Der Wert ist ein Ergebnisbaum-Fragment, welches zu einer Knotenmenge mit nur einem Wurzelknoten equivalent ist, der als Kinder die Folge von Knoten enthält, die durch die Instanziierung des Templates entstehen. Der Basis-URI der Knoten im Ergebnisbaum-Fragment ist der Basis-URI des variablenbindenden Elements.

    Ein Fehler tritt auf, wenn ein Knoten in dieser Knotenfolge, der durch die Instanziierung des Templates erzeugt wurde, ein Attributknoten oder ein Namensraumknoten ist, da ein Wurzelknoten keinen Attributknoten oder Namensraumknoten als Kind haben kann. Ein XSLT-Prozessor kann den Fehler anzeigen; falls er den Fehler nicht anzeigt, muss er weiterarbeiten, indem er den Attributknoten oder Namensraumknoten nicht hinzufügt.

  • Wenn das variablenbindende Element einen leeren Inhalt hat und kein select-Attribut besitzt, ist der Wert der Variablen eine leere Zeichenkette. Somit ist

    <xsl:variable name="x"/>

    equivalent zu

    <xsl:variable name="x" select="''"/>

Anmerkung:

Wenn eine Variable benutzt wird, um Knoten anhand der Position auszuwählen, ist Folgendes zu vermeiden:

<xsl:variable name="n">2</xsl:variable>
...
<xsl:value-of select="item[$n]"/>

Dies wird den Wert des ersten Elements ausgeben, da die Variable n an ein Ergebnisbaum-Fragment gebunden wird, nicht an eine Zahl. Benutzen Sie stattdessen entweder

<xsl:variable name="n" select="2"/>
...
<xsl:value-of select="item[$n]"/>

oder

<xsl:variable name="n">2</xsl:variable>
...
<xsl:value-of select="item[position()=$n]"/>

Anmerkung:

Eine brauchbare Möglichkeit, eine leere Knotenmenge als Vorgabewert eines Parameters anzugeben, ist:

<xsl:param name="x" select="/.."/>

11.3 Benutzen von Variablen- und Parameterwerten mit xsl:copy-of

<!-- Kategorie: Anweisung -->
<xsl:copy-of
select = | expression
/>

Das xsl:copy-of-Element kann dazu benutzt werden, ein Ergebnisbaum-Fragment in einen Ergebnisbaum einzufügen, ohne es vorher in eine Zeichenkette umzuwandeln, wie es bei xsl:value-of geschieht (siehe 7.6.1 Generierung von Text mit xsl:value-of ). Das notwendige select-Attribut enthält einen Ausdruck. Wenn das Ergebnis der Auswertung ein Ergebnisbaum-Fragment ist, wird das gesamte Fragment in den Ergebnisbaum kopiert. Falls das Ergebnis eine Knotenmenge ist, werden alle Knoten der Menge in der Dokumentreihenfolge in den Ergebnisbaum kopiert; das Kopieren eines Elementknotens kopiert die Attributknoten, Namensraumknoten und Kinder des Elementknotens sowie den Elementknotens selbst; ein Wurzel-Knoten wird kopiert, indem seine Kinder kopiert werden. Wenn ein Ergebnis weder eine Knotenmenge noch ein Ergebnisbaum-Fragment ist, wird das Ergebnis in eine Zeichenkette gewandelt und anschließend – wie mit xsl:value-of – in den Ergebnisbaum eingefügt.

11.4 Variablen und Parameter auf der obersten Ebene

Sowohl xsl:variable als auch xsl:param sind als Elemente in der obersten Ebene erlaubt. Ein variablenbindendes Element auf oberster Ebene vereinbart eine globale Variable, die überall sichtbar ist. Ein xsl:param-Element auf oberster Ebene vereinbart einen Parameter für das Stylesheet; XSLT definiert keinen Mechanismus, mit dem Parameter an das Stylesheet übergeben werden. Falls ein Stylesheet mehr als eine Bindung einer Variablen auf oberster Ebene mit demselben Namen und derselben Importpriorität enthält, ist dies ein Fehler. Auf der obersten Ebene wird der Ausdruck oder das Template, das den Variablenwert spezifiziert, mit demselben Kontext ausgewertet, der benutzt wird, um den Wurzelknoten des Quelldokuments zu verarbeiten: Der aktuelle Knoten ist der Wurzelknoten des Quelldokuments und die aktuelle Knotenliste ist eine Liste, die nur das Wurzelelement des Quelldokuments enthält. Falls durch das Template oder den Ausdruck, der den Wert einer globalen Variablen x spezifiziert, eine globale Variable y referenziert wird, muss der Wert für y vor dem Wert von x berechnet werden. Falls dies nicht für alle globalen Variablen möglich ist, ist dies ein Fehler; in anderen Worten ist es ein Fehler, wenn Definitionen Zykel enthalten.

Das Beispiel deklariert eine globale Variable para-font-size, die in einem Attributwert-Template referenziert wird:

<xsl:variable name="para-font-size">12pt</xsl:variable>

<xsl:template match="para">
 <fo:block font-size="{$para-font-size}">
   <xsl:apply-templates/>
 </fo:block>
</xsl:template>

11.5 Variablen und Parameter innerhalb von Templates

Ebenso wie xsl:variable und xsl:param auf oberster Ebene erlaubt sind, sind sie in Templates erlaubt. xsl:variable ist an allen Stellen innerhalb eines Templates erlaubt, an denen eine Anweisung erlaubt wäre. In diesem Fall ist die Bindung für alle folgenden Geschwister und deren Nachfahren sichtbar. Zu beachten ist, dass die Bindung nicht für das xsl:variable-Element selbst sichtbar ist. xsl:param ist als Kind am Anfang eines xsl:template-Elements erlaubt. In diesem Kontext ist die Bindung für alle folgenden Geschwister und deren Nachfahren sichtbar. Beachten Sie, dass die Bindung für das xsl:param-Element selbst nicht sichtbar ist.

[Definition: Eine Bindung verdeckt eine andere Bindung, wenn die Bindung an einem Punkt auftritt, an dem die andere Bindung sichtbar ist und die Bindungen den gleichen Namen haben.] Es ist ein Fehler, wenn eine Bindung, die durch ein xsl:variable- oder xsl:param-Element hergestellt wurde, innerhalb eines Templates eine andere Bindung innerhalb des Templates verdeckt, die ebenfalls durch ein xsl:variable- oder xsl:param-Element hergestellt wurde. Es ist kein Fehler, wenn eine Bindung, die durch ein xsl:variable- oder xsl:param-Element in einem Template hergestellt wurde, eine andere Bindung verdeckt, die durch ein xsl:variable oder ein xsl:param auf oberster Ebene hergestellt wurde.

Entsprechend führt Folgendes zu einem Fehler:

<xsl:template name="foo">
<xsl:param name="x" select="1"/>
<xsl:variable name="x" select="2"/>
</xsl:template>

Jedoch ist Folgendes erlaubt:

<xsl:param name="x" select="1"/>
<xsl:template name="foo">
<xsl:variable name="x" select="2"/>
</xsl:template>

Anmerkung:

Das am besten entsprechende Konstrukt in Java zu einem xsl:variable-Element in einem Template ist eine finale lokale Variablendeklaration mit einer Initialisierung. Beispielsweise ist

<xsl:variable name="x" select="'value'"/>

gleichbedeutend mit

final Object x = "value";

XSLT stellt kein Equivalent zum Java-Zuweisungsoperator

x = "value";

zur Verfügung, da dies Implementierungen erschweren würde, die ein Dokument anders als Batch-artig, am Anfang startend und zum Ende fortschreitend, verarbeiten.

11.6 Parameterübergabe an Templates

<xsl:with-param
name = | qname
select = | expression
>
<!-- Inhalt: template -->
</xsl:with-param

Parameter werden an Templates mit Hilfe des xsl:with-param-Elements übergeben. Das benötigte name-Attribut gibt den Namen des Parameters an (bzw. den Namen der Variablen, bei der der Wert ihrer Bindung ersetzt werden soll). Der Wert des name-Attributs ist ein QName, welcher wie in 2.4 Qualifizierte Namen beschrieben erweitert wird. xsl:with-param ist sowohl innerhalb von xsl:call-template als auch innerhalb von xsl:apply-templates erlaubt. Der Wert des Parameters wird in derselben Weise angegeben, wie für xsl:variable und xsl:param. Der aktuelle Knoten und die aktuelle Knotenliste, die für die Berechnung des Wertes benutzt wird, der durch das xsl:with-param-Element angegeben ist, ist dieselbe wie für das xsl:apply-template- oder xsl:call-template-Element, in dem es auftritt. Es ist kein Fehler, einen Parameter x an ein Template zu übergeben, das kein xsl:param-Element für x besitzt; der Parameter wird einfach ignoriert.

Das folgende Beispiel definiert ein benanntes Template für einen nummerierten Absatz (numbered-block) mit einem Argument, um das Format der Nummerierung zu kontrollieren:

<xsl:template name="numbered-block">
  <xsl:param name="format">1. </xsl:param>
  <fo:block>
    <xsl:number format="{$format}"/>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<xsl:template match="ol//ol/li">
  <xsl:call-template name="numbered-block">
    <xsl:with-param name="format">a. </xsl:with-param>
  </xsl:call-template>
</xsl:template>

12 Zusätzliche Funktionen

Dieses Kapitel beschreibt XSLT-spezifische Zusätze zu der elementaren XPath-Funktionsbibliothek. Einige dieser Zusätze benutzen Informationen, die durch Elemente auf oberster Ebene im Stylesheet angegeben werden; diese Elemente werden ebenfalls in diesem Abschnitt beschrieben.

12.1 Mehrere Quelldokumente

node-set document( , object , node-set? )

Die document-Funktion erlaubt den Zugriff auf andere XML-Dokumente außerhalb des Hauptquelldokuments.

Wenn die document-Funktion genau ein Argument hat und dieses Argument eine Knotenmenge ist, so ist das Ergebnis die Vereinigung der Ergebnisse jedes Knotens in der Argument-Knotenmenge bei Aufruf der document-Funktion mit dem Zeichenkettenwert des Knotens als erstem Argument und einer Knotenmenge mit dem Knoten als einzigem Mitglied als zweitem Argument. Falls die document-Funktion zwei Argumente hat und das erste Argument eine Knotenmenge ist, so ist das Ergebnis die Vereinigung der Ergebnisse jedes Knotens in der Argument-Knotenmenge bei Aufruf der document-Funktion mit dem Zeichenkettenwert des Knotens als erstem Argument und dem zweiten Argument, das der document-Funktion übergeben wurde, als zweitem Argument.

Wenn das erste Argument der document-Funktion keine Knotenmenge ist, wird das erste Argument wie durch einen Aufruf der string-Funktion in eine Zeichenkette gewandelt. Diese Zeichenkette wird wie eine URI-Referenz behandelt; die Ressource, die durch den URI angegeben ist, wird herangezogen. Der aus dieser Aktion resultierende Inhalt wird als XML-Dokument analysiert und ein Baum in Übereinstimmung mit dem Datenmodell (siehe 3 Datenmodell) konstruiert. Falls beim Holen der Ressource ein Fehler auftritt, darf der XSLT-Prozessor einen Fehler anzeigen; falls er keinen Fehler anzeigt, muss er weiterarbeiten, indem er eine leere Knotenmenge zurückliefert. Eine mögliche Fehlerart beim Holen der Ressource besteht darin, dass der XSLT-Prozessor das URI-Schema nicht unterstützt, das von dem URI verwendet wird. Es wird nicht verlangt, dass ein XSLT-Prozessor alle möglichen URI-Schemata unterstützt. In der Dokumentation eines XSLT-Prozessors sollte angegeben sein, welche URI-Schemata der XSLT-Prozessor unterstützt.

Falls die URI-Referenz keinen Fragmentverweis enthält, wird eine Knotenmenge zurückgeliefert, die nur den Wurzelknoten des Dokuments enthält. Falls die URI-Referenz einen Fragmentverweis enthält, gibt die Funktion eine Knotenmenge zurück, die jene Knoten des Baums enthält, die durch den Fragmentverweis der URI-Referenz angegeben sind. Die Semantik des Fragmentverweises hängt vom Medientyp des Ergebnisses des Holens der URI-Ressource ab. Falls ein Fehler bei der Verarbeitung des Fragmentverweises auftritt, kann der XSLT-Prozessor einen Fehler anzeigen; falls er dies nicht tut, muss er weiterarbeiten, indem er eine leere Knotenmenge zurückliefert. Mögliche Fehler sind unter anderem:

  • Der Teilstückverweis bezeichnet etwas, das nicht als XSLT-Knotenmenge gesehen werden kann (z.B. einen Bereich von Textzeichen innerhalb eines Textknotens).

  • Der XSLT-Prozessor unterstützt den Fragmentverweis für den Medientyp des Ergebnisses des Holens der Ressource nicht. Es wird nicht verlangt, dass ein XSLT-Prozessor alle möglichen Medientypen unterstützt. Die Dokumentation für einen XSLT-Prozessor sollte angeben, für welchen Medientyp der XSLT-Prozessor Fragmentverweise unterstützt.

Der Inhalt des Holens der Ressource wird als XML-Dokument analysiert, ohne Beachtung des Medientyps des Ergebnisses des Holens der Ressource; falls der Medientyp der obersten Ebene text ist, wird das XML-Dokument so analysiert, als wenn der Medientyp text/xml wäre; ansonsten wird es in der gleichen Art analysiert, als wenn der Medientyp application/xml wäre.

Anmerkung:

Da kein Medientyp xml auf oberster Ebene existiert, kann der Inhalt mit einem anderen Medientyp als text/xml oder application/xml tatsächlich XML sein.

Der URI-Verweis kann relativ sein. Es wird der Basis-URI (siehe 3.2 Basis-URI) des in Dokumentreihenfolge ersten Knotens der Knotenmenge des zweiten Arguments benutzt, um den relativen URI in einen absoluten URI aufzulösen. Falls das zweite Argument ausgelassen wird, wird es als Vorgabe auf den Knoten im Stylesheet gesetzt, der den Ausdruck enthält, der den Aufruf der document-Funktion beinhaltet. Beachten Sie, dass eine URI-Referenz der Länge Null eine Referenz zu dem Dokument ist, relativ zu dem die URI-Referenz aufgelöst wird; folglich bezieht sich document("") auf den Wurzelknoten des Stylesheets; die Baumdarstellung des Stylesheets ist exakt die gleiche, als wenn das XML-Dokument, welches das Stylesheet enthält, das initiale Quelldokument wäre.

Zwei Dokumente gelten als dasselbe Dokument, wenn sie durch den gleichen URI bezeichnet werden. Der URI, der für den Vergleich benutzt wird, ist der absolute URI, in den alle relativen URIs aufgelöst wurden, und er enthält keinen Fragmentverweis. Ein Wurzelknoten wird als derselbe Wurzelknoten angesehen, wenn die beiden Knoten vom selben Dokument sind. Daher ist der folgende Ausdruck immer wahr:

generate-id(document("foo.xml"))=generate-id(document("foo.xml"))

Durch die document-Funktion ergibt sich die Möglichkeit, dass eine Knotenmenge Knoten von mehr als einem Dokument enthalten kann. In einer solchen Knotenmenge ist die relative Dokumentreihenfolge zweier Knoten desselben Dokuments die normale durch XPath [XPath] definierte Dokumentreihenfolge. Die relative Dokumentreihenfolge zweier Knoten aus unterschiedlichen Dokumenten wird durch eine implementierungs-abhängige Reihenfolge der Dokumente, welche die beiden Knoten enthalten, bestimmt. Es gibt keine Vorgabe, wie eine Implementierung Dokumente ordnet, außer dass sie es konsistent tut: Eine Implentierung muss immer die gleiche Reihenfolge für die gleiche Menge von Dokumenten benutzen.

12.2 Schlüssel

Schlüssel stellen eine Möglichkeit zur Verfügung, mit Dokumenten zu arbeiten, die eine implizite kreuzreferenzierte Struktur enthalten. Die ID-, IDREF- und IDREFS-Attributtypen in XML stellen einen Mechanismus zur Verfügung, der es XML-Dokumenten erlaubt, ihre Kreuzreferenzen explizit zu machen. XSLT unterstützt dies durch die XPath id-Funktion. Allerdings besitzt dieser Mechanismus eine Reihe von Einschränkungen:

  • ID-Attribute müssen als solche in der DTD deklariert werden. Falls ein ID-Attribut nur in einem externen DTD-Teilbereich als ID-Attribut deklariert ist, wird es nur als ID-Attribut erkannt, wenn der XML-Prozessor den externen DTD-Teilbereich einliest. XML verlangt jedoch von XML-Prozessoren nicht, die externe DTD einzulesen, und es kann eine gute Wahl sein, dies nicht zu tun, vor allem, wenn das Dokument mit standalone="yes" deklariert wird.

  • Ein Dokument kann nur eine Menge einzigartiger IDs enthalten. Getrennte, unabhängige Mengen einzigartiger IDs können nicht vorkommen.

  • Die ID eines Elements kann nur in einem Attribut spezifiziert werden; sie kann nicht durch den Inhalt oder durch ein Kindelement spezifiziert werden.

  • Eine ID muss zwangsweise ein XML-Name sein. Er kann zum Beispiel keine Leerzeichen enthalten.

  • Ein Element kann maximal eine ID besitzen.

  • Maximal ein Element kann eine bestimmte ID besitzen.

Auf Grund dieser Einschränkungen enthalten XML-Dokumente manchmal eine Kreuzreferenz-Struktur, die nicht explizit durch ID-/IDREF-/IDREFS-Attribute deklariert ist.

Ein Schlüssel ist ein Tripel, der Folgendes enthält:

  1. den Knoten, der den Schlüssel enthält,

  2. den Namen des Schlüssels (ein Erweiterter Name),

  3. den Wert des Schlüssels (eine Zeichenkette).

Ein Stylesheet deklariert eine Menge von Schlüsseln für jedes Dokument mit Hilfe des xsl:key-Elements. So diese Menge von Schlüsseln einen Schlüssel mit Knoten x, Namen y und Wert z enthält, sagen wir, dass Knoten x einen Schlüssel mit Namen y und Wert z besitzt.

Folglich ist ein Schlüssel eine Art generalisierter ID, die nicht den gleichen Einschränkungen unterliegt wie XML:

  • Schlüssel werden in einem Stylesheet mit Hilfe des xsl:key-Elements deklariert.

  • Ein Schlüssel hat sowohl einen Namen als auch einen Wert; jeder Schlüsselname kann so gesehen werden, als wenn er einen separaten, unabhängigen Raum von Identifizierern unterscheidet.

  • Der Wert eines benannten Schlüssels für ein Element kann an jedem passenden Platz spezifiziert werden; zum Beispiel in einem Attribut, in einem Kindelement oder im Inhalt. Ein XPath-Ausdruck wird verwendet, um zu spezifizieren, wo der Wert für einen bestimmten benannten Schlüssel zu finden ist.

  • Der Wert eines Schlüssels kann eine beliebige Zeichenkette sein; er muss nicht zwangsweise ein Name sein.

  • Es können mehrere Schlüssel in einem Dokument mit demselben Knoten, demselben Schlüsselnamen aber unterschiedlichen Schlüsselwerten vorkommen.

  • Es können mehrere Schlüssel in einem Dokument mit demselben Schlüsselnamen, demselben Schlüsselwert aber unterschiedlichen Knoten vorkommen.

<!-- Kategorie: top-level-element -->
<xsl:key
name = | qname
match = | pattern
use = | expression
/>

Das xsl:key-Element wird zur Deklaration von Schlüsseln verwendet. Das name-Attribut gibt den Namen des Schlüssels an. Der Wert des name-Attributs ist ein QName, der wie in 2.4 Qualifizierte Namen beschrieben erweitert wird. Das match-Attribut ist ein Muster; ein xsl:key-Element gibt Informationen über die Schlüssel jedes Knotens, der zu dem Muster, das im match-Attribut angegeben ist, passt. Das use-Attribut ist ein Ausdruck, der den Wert des Schlüssels angibt; der Ausdruck wird einmalig für jeden Knoten ausgewertet, der zu dem Muster passt. Falls das Ergebnis eine Knotenmenge ist, so gilt für jeden Knoten in der Knotenmenge, dass der Knoten, zu dem das Muster passt, einen Schlüssel mit dem angegebenen Namen besitzt, dessen Wert der Zeichenkettenwert des Knotens in der Knotenmenge ist; anderenfalls wird das Ergebnis in eine Zeichenkette umgewandelt, und der Knoten, der zu dem Muster passt, besitzt einen Schlüssel mit dem angegebenen Namen und einem zu der Zeichenkette equivalenten Wert. Folglich hat ein Knoten x einen Schlüssel mit Namen y und Wert z dann und nur dann, wenn ein xsl:key-Element vorhanden ist, für das gilt:

  • x passt zu dem Muster, das im match-Attribut des xsl:key-Elements spezifiziert ist;

  • der Wert des name-Attributs des xsl:key-Elements ist equivalent zu y; und

  • falls der Ausdruck, der im use-Attribut des xsl:key-Elements angegeben ist, mit x als dem aktuellen Knoten und mit einer Knotenliste ausgewertet wird, die nur x als aktuelle Knotenliste enthält, woraus ein Objekt u resultiert, für das dann entweder z equivalent zu dem Ergebnis der Umwandlung von u in eine Zeichenkette ist, wie durch einen Aufruf der string-Funktion, oder u ist eine Knotenmenge und z ist equivalent zum Zeichenkettenwert von einem oder mehreren der Knoten in u.

Beachten Sie ebenfalls, dass mehr als ein xsl:key-Element existieren kann, das zu einem gegebenen Knoten passt; alle passenden xsl:key-Elemente werden verwendet, selbst wenn sie nicht die gleiche Importpriorität besitzen.

Es ist ein Fehler, falls entweder der Wert des use-Attributs oder der Wert des match-Attributs eine Variablenreferenz enthält.

node-set key( , string , object )

Die key-Funktion macht für Schlüssel das, was die id-Funktion für IDs tut. Das erste Argument gibt den Namen des Schlüssels an. Der Wert des Arguments muss ein QName sein, der wie in 2.4 Qualifizierte Namen beschrieben erweitert wird. Falls das zweite Argument der key-Funktion vom Typ Knotenmenge ist, ist das Ergebnis die Vereinigung der Ergebnisse der Anwendung der key-Funktion auf den Zeichenkettenwert jedes Knotens in der Argumentknotenmenge. Falls das zweite Argument von key von einem anderen Typ ist, wird das Argument wie durch einen Aufruf der string-Funktion in eine Zeichenkette umgewandelt; zurückgegeben wird eine Knotenmenge, die solche Knoten desselben Dokuments, in dem sich der Kontextknoten befindet, enthält, die einen Wert für den benannten Schlüssel besitzen, der gleich der Zeichenkette ist.

Beispielsweise sei folgende Deklaration gegeben:

<xsl:key name="idkey" match="div" use="@id"/>

Ein Ausdruck key("idkey",@ref) wird die gleiche Knotenmenge zurückliefern wie id(@ref), vorausgesetzt, das einzige deklarierte ID-Attribut im XML-Quelldokument ist

<!ATTLIST div id ID #IMPLIED>

und vorausgesetzt, das ref-Attribut des aktuellen Knotens enthält keinen Leerraum.

Angenommen, ein Dokument beschreibt eine Funktionsbibliothek und verwendet ein prototype-Element, um Funktionen zu definieren,

<prototype name="key" return-type="node-set">
<arg type="string"/>
<arg type="object"/>
</prototype>

und ein function-Element, um Funktionsnamen zu referenzieren,

<function>key</function>

dann könnte das Stylesheet Hyperlinks zwischen den Referenzen und Definitionen wie folgt generieren:

<xsl:key name="func" match="prototype" use="@name"/>

<xsl:template match="function">
<b>
  <loc href="#{generate-id(key('func',.))}">
    <xsl:apply-templates/>
  </loc>
</b>
</xsl:template>

<xsl:template match="prototype">
<p><a name="{generate-id()}">
<b>Function: </b>
...
</loc></p>
</xsl:template>

Die key-Funktion kann verwendet werden, um einen Schlüssel aus einem anderen Dokument als dem Dokument, das den Kontextknoten enthält, zu erhalten.

Angenommen, ein Dokument enthalte zum Beispiel bibliografische Referenzen der Form <bibref>XSLT</bibref> und es gäbe ein separates XML-Dokument bib.xml, das eine bibliografische Datenbank mit Einträgen in folgender Form enthält:

<entry name="XSLT">...</entry>

Dann kann das Stylesheet Folgendes verwenden, um die bibref-Elemente umzuwandeln:

<xsl:key name="bib" match="entry" use="@name"/>

<xsl:template match="bibref">
  <xsl:variable name="name" select="."/>
  <xsl:for-each select="document('bib.xml')">
    <xsl:apply-templates select="key('bib',$name)"/>
  </xsl:for-each>
</xsl:template>

12.3 Zahlenformatierung

string format-number( , number , string , string? )

Die format-number-Funktion konvertiert ihr erstes Argument zu einer Zeichenkette, indem sie die Formatmuster-Zeichenkette verwendet, die als zweites Argument angegeben ist, und das Dezimalformat verwendet, das durch das dritte Argument angegeben ist, oder das Vorgabe-Dezimalformat verwendet, falls kein drittes Argument vorhanden ist. Die Syntax der Formatmuster-Zeichenkette wird durch die JDK 1.1 DecimalFormat-Klasse spezifiziert. Die Formatmuster-Zeichenkette wird in einer lokalisierten Form angegeben: das Dezimalformat bestimmt, welche Zeichen eine besondere Bedeutung innerhalb des Musters haben (mit Ausnahme des Apostrophzeichens, das nicht lokalisiert ist). Das Formatmuster darf kein Währungszeichen (#x00A4) enthalten; Unterstützung für diese Fähigkeit wurde erst nach der ersten Veröffentlichung des JDK 1.1 hinzugefügt. Der Dezimalformat-Name muss ein QName sein, der wie in 2.4 Qualifizierte Namen beschrieben erweitert wird. Es ist ein Fehler, falls das Stylesheet keine Deklaration des Dezimalformats durch den angegebenen erweiterten Namen enthält.

Anmerkung:

Es wird weder verlangt, dass Implementierungen das JDK 1.1 verwenden, noch dass sie in Java implementiert werden.

Anmerkung:

Stylesheets können andere Einrichtungen von XPath verwenden, um die Rundung zu kontrollieren.

<!-- Kategorie: top-level-element -->
<xsl:decimal-format
name = | qname
decimal-separator = | char
grouping-separator = | char
infinity = | string
minus-sign = | char
NaN = | string
percent = | char
per-mille = | char
zero-digit = | char
digit = | char
pattern-separator = | char
/>

Das xsl:decimal-format-Element deklariert ein Dezimalformat, das die Interpretation eines Formatmusters kontrolliert, das von der format-number-Funktion verwendet wird. Falls ein name-Attribut vorhanden ist, deklariert das Element ein benanntes Dezimalformat; ansonsten deklariert es das Vorgabe-Dezimalformat. Der Wert des name-Attributs ist ein QName, der wie in 2.4 Qualifizierte Namen beschrieben erweitert wird. Es ist ein Fehler, wenn entweder das Vorgabe-Dezimalformat oder ein benanntes Dezimalformat mehr als einmal deklariert wird (selbst mit unterschiedlicher Importpriorität), es sei denn, es wird jedes Mal mit den gleichen Werten für alle Attribute deklariert (unter Berücksichtigung aller Vorgabewerte).

Die anderen Attribute für xsl:decimal-format korrespondieren zu den Methoden der JDK 1.1 DecimalFormatSymbols-Klasse. Für jedes get/set-Methodenpaar wird ein Attribut für das xsl:decimal-format-Element definiert.

Die folgenden Attribute kontrollieren die Interpretation der Zeichen im Formatmuster und geben die Zeichen an, die im Ergebnis der Zahlenformatierung auftreten dürfen:

  • decimal-separator gibt das Zeichen an, das als Dezimal-Zeichen verwendet wird; der Vorgabewert ist das Periodenzeichen (.).

  • grouping-separator gibt das Zeichen an, das zur Trennung von Gruppen (z.B. Tausender) verwendet wird; der Vorgabewert ist das Kommazeichen (,).

  • percent gibt das Zeichen an, das als Prozentzeichen verwendet wird; der Vorgabewert ist das Prozentzeichen (%).

  • per-mille gibt das Zeichen an, das als 'pro-tausend'-Zeichen verwendet wird; der Vorgabewert ist das Unicode Per-mille-Zeichen (#x2030).

  • zero-digit gibt das Zeichen an, das als Ziffer Null verwendet wird; der Vorgabewert ist die Ziffer Null (0).

Die folgenden Attribute kontrollieren die Interpretation von Zeichen im Formatmuster:

  • digit gibt das Zeichen an, das für eine Ziffer im Formatmuster verwendet wird; der Vorgabewert ist das Nummernzeichen (#).

  • pattern-separator gibt das Zeichen an, das verwendet wird, um positive und negative Untermuster in einem Muster zu trennen; der Vorgabewert ist das Semikolon (;).

Die folgenden Attribute geben Zeichen oder Zeichenketten an, die in dem Ergebnis der Zahlenformatierung auftreten dürfen:

  • infinity gibt die Zeichenkette an, die unendlich repräsentiert; der Vorgabewert ist die Zeichenkette Infinity.

  • NaN gibt die Zeichenkette an, die den NaN-Wert repräsentiert; der Vorgabewert ist die Zeichenkette NaN.

  • minus-sign gibt das Zeichen an, das als Vorgabe-Minuszeichen verwendet wird; der Vorgabewert ist das Bindestrich-/Minus-Zeichen (-, #x2D).

12.4 Diverse zusätzliche Funktionen

node-set current()

Die current-Funktion gibt eine Knotenmenge zurück, welche den aktuellen Knoten als einziges Element der Menge besitzt. Für einen äußeren Ausdruck (einen Ausdruck, der nicht innerhalb eines anderen Ausdrucks auftritt) ist der aktuelle Knoten immer derselbe wie der Kontextknoten. Folglich bedeutet

<xsl:value-of select="current()"/>

das Gleiche wie

<xsl:value-of select="."/>

Dennoch ist der aktuelle Knoten innerhalb von eckigen Klammern üblicherweise vom Kontextknoten verschieden. Zum Beispiel verarbeitet

<xsl:apply-templates select="//glossary/item[@name=current()/@ref]"/>

alle item-Elemente, die ein glossary-Vaterelement und ein name-Attribut mit einem Wert, der mit dem Wert des ref-Attributs des aktuellen Knotens übereinstimmt, besitzen. Dies unterscheidet sich von

<xsl:apply-templates select="//glossary/item[@name=./@ref]"/>

was gleichbedeutend ist mit

<xsl:apply-templates select="//glossary/item[@name=@ref]"/>

und auf diese Weise alle item-Elemente verarbeiten würde, die ein glossary-Vaterelement und ein name-Attribut und ein ref-Attribut mit dem gleichen Wert besitzen.

Es ist ein Fehler, die current-Funktion in einem Muster zu verwenden.

string unparsed-entity-uri( , string )

Die unparsed-entity-uri-Funktion gibt den URI der nicht analysierten Entity mit dem angegebenen Namen im selben Dokument wie der Kontextknoten zurück (siehe 3.3 Nicht analysierte Entitys). Sie gibt eine leere Zeichenkette zurück, falls kein derartiges Entity vorhanden ist.

string generate-id( , node-set? )

Die generate-id-Funktion gibt eine Zeichenkette zurück, die den in der Dokumentreihenfolge ersten Knoten der Argument-Knotenmenge eindeutig bezeichnet. Die eindeutige Bezeichnung muss aus alphanumerischen ASCII-Zeichen bestehen und mit einem alphabetischen Zeichen beginnen. Folglich ist der String syntaktisch ein XML-Name. Eine Implementierung kann einen Bezeichner auf jede passende Art und Weise erzeugen, vorausgesetzt, sie erzeugt immer denselben Bezeichner für denselben Knoten und sie erzeugt immer unterschiedliche Bezeichner aus unterschiedlichen Knoten. Eine Implementierung ist nicht verpflichtet, bei jeder Transformation eines Dokuments die gleichen Bezeichner zu generieren. Es wird nicht garantiert, dass sich ein erzeugter eindeutiger Bezeichner von allen eindeutigen im Quelldokument angegebenen IDs unterscheidet. Falls die Argument-Knotenmenge leer ist, wird eine leere Zeichenkette zurückgegeben. Falls das Argument weggelassen wird, wird als Vorgabe der Kontextknoten verwendet.

object system-property( , string )

Das Argument muss sich zu einer Zeichenkette auswerten lassen, die ein QName ist. Der QName wird unter Verwendung der Namensraum-Deklarationen im Bereich des Ausdrucks in einen Namen erweitert. Die system-property-Funktion gibt ein Objekt zurück, das den Wert der Systemeigenschaft repräsentiert, die durch den Namen identifiziert wird. Falls keine solche Systemeigenschaft existiert, sollte eine leere Zeichenkette zurückgeliefert werden.

Implementierungen müssen die folgenden Systemeigenschaften zur Verfügung stellen, die alle im XSLT-Namensraum liegen:

  • xsl:version, eine Zahl, welche die XSLT-Version angibt, die der Prozessor implementiert; für XSLT-Prozessoren, welche die von diesem Dokument spezifizierte Version von XSLT implementieren, ist dies die Zahl 1.0.
  • xsl:vendor, eine Zeichenkette, die den Hersteller des XSLT-Prozessors angibt
  • xsl:vendor-url, eine Zeichenkette, die den URL enthält, der den Hersteller des XSLT-Prozessors identifiziert; üblicherweise ist dies die Adresse der Homepage des Herstellers.

13 Nachrichten

<!-- Kategorie: instruction -->
<xsl:message
terminate = | "yes" | "no"
>
<!-- Inhalt: template -->
</xsl:message

Die xsl:message-Anweisung versendet eine Nachricht in einer Art und Weise, die vom XSLT-Prozessor abhängig ist. Der Inhalt der xsl:message-Anweisung ist ein Template. xsl:message wird instanziiert, indem der Inhalt instanziiert wird, um ein XML-Fragment zu erzeugen. Dieses XML-Fragment ist der Inhalt der Nachricht.

Anmerkung:

Ein XSLT-Prozessor könnte xsl:message durch das Öffnen eines Nachrichtenfensters oder durch Schreiben in eine Log-Datei implementieren.

Falls das terminate-Attribut den Wert yes besitzt, sollte der XSLT-Prozessor die Verarbeitung beenden, nachdem er die Nachricht versendet hat. Der Vorgabewert ist no.

Eine geeignete Art, Sprachlokalisierung vorzunehmen, besteht darin, die lokalisierten Informationen (Nachrichten, Text etc.) in einem XML-Dokument abzulegen, das als zusätzliche Quelldatei für das Stylesheet verwendet wird. Beispielsweise seien Nachrichten für eine Sprache L in einer XML-Datei resources/L.xml in folgender Form gespeichert:

<messages>
  <message name="problem">A problem was detected.</message>
  <message name="error">An error was detected.</message>
</messages>

Dann könnte ein Stylesheet den folgenden Ansatz für lokalisierte Nachrichten verwenden:

<xsl:param name="lang" select="'en'"/>
<xsl:variable name="messages"
  select="document(concat('resources/', $lang, '.xml'))/messages"/>

<xsl:template name="localized-message">
  <xsl:param name="name"/>
  <xsl:message>
    <xsl:value-of select="$messages/message[@name=$name]"/>
  </xsl:message>
</xsl:template>

<xsl:template name="problem">
  <xsl:call-template name="localized-message"/>
    <xsl:with-param name="name">problem</xsl:with-param>
  </xsl:call-template>
</xsl:template>

14 Erweiterungen

XSLT erlaubt die zwei Erweiterungsarten: Erweiterungselemente und Erweiterungsfunktionen.

Diese Version von XSLT stellt keinen Mechanismus zur Verfügung, um die Implementierung von Erweiterungen zu definieren. Folglich kann sich ein XSLT-Stylesheet, das zwischen XSLT-Implementierungen portabel sein muss, nicht auf speziell verfügbare Erweiterungen verlassen. XSLT stellt Mechanismen zur Verfügung, die es einem XSLT-Stylesheet erlauben, zu bestimmen, ob der XSLT-Prozessor, von dem das Stylesheet verarbeitet wird, Implementierungen spezieller Erweiterungen zur Verfügung stellt und anzugeben, was passieren soll, falls diese Erweiterungen nicht verfügbar sind. Falls ein XSLT-Stylesheet sorgsam ist und diese Mechanismen verwendet, ist es möglich, Vorteile der Erweiterungen zu nutzen und weiterhin mit jeder XSLT-Implementation zu arbeiten.

14.1 Erweiterungselemente

[Definition: Der Elementerweiterungsmechanismus erlaubt die Auszeichnung von Namensräumen als Erweiterungsnamensräume. Falls ein Namensraum als Erweiterungsnamensraum ausgezeichnet ist und ein Element mit einem Namen aus diesem Namensraum in einem Template vorkommt, wird das Element als Anweisung statt als ein literales Ergebniselement behandelt.] Der Namensraum bestimmt die Semantik der Anweisung.

Anmerkung:

Da ein Element, das ein Kind eines xsl:stylesheet-Elements ist, nicht in einem Template vorkommt, sind Nicht-XSLT-Elemente auf oberster Ebene keine Erweiterungselemente wie hier definiert und nichts in diesem Abschnitt gilt für sie.

Ein Namensraum wird als Erweiterungsnamensraum ausgezeichnet, indem ein extension-element-prefixes-Attribut in dem xsl:stylesheet-Element oder ein xsl:extension-element-prefixes-Attribut in einem literalen Ergebniselement oder Erweiterungselement verwendet wird. Der Wert dieser beiden Attribute ist eine durch Leerräume getrennte Liste von Namensraum-Präfixen. Der an jedes Präfix gebundene Namensraum wird als Erweiterungsnamensraum ausgezeichnet. Es ist ein Fehler, falls kein Namensraum an das Präfix des Elements gebunden ist, das das extension-element-prefixes- oder xsl:extension-element-prefixes-Attribut enthält. Der Vorgabenamensraum (durch xmlns deklariert) kann als ein Erweiterungsnamensraum ausgezeichnet werden, indem #default in die Liste der Namensraum-Präfixe eingefügt wird. Die Auszeichnung eines Namensraumes als Erweiterungsnamensraum ist innerhalb des Unterbaums des Stylesheets von Effekt, dessen Wurzelknoten das Element ist, welches das extension-element-prefixes- oder das xsl:extension-element-prefixes-Attribut enthält; der Unterbaum, dessen Wurzel ein xsl:stylesheet-Element ist, enthält keine Stylesheets, die durch Kindknoten des xsl:stylesheet-Elements importiert oder eingebunden werden.

Falls ein XSLT-Prozessor keine Implementierung eines speziellen Erweiterungselements hat, muss die element-available-Funktion für Namen des Elements false zurückliefern. Wenn solch ein Erweiterungselement instanziiert wird, muss der XSLT-Prozessor einen Rückgriff für das Element bieten, wie in 15 Rückgriff beschrieben. Ein XSLT-Prozessor darf keine Fehler anzeigen, bloß weil ein Template ein Erweiterungselement enthält, für das keine Implementierung vorhanden ist.

Falls der XSLT-Prozessor eine Implementierung einer speziellen Erweiterungsfunktion anbietet, muss die element-available-Funktion für den Namen des Elements true zurückliefern.

14.2 Erweiterungsfunktionen

Falls ein Funktionsname in einem Funktionsaufruf-Ausdruck kein NCName ist (z.B. falls er ein Komma enthält), wird er behandelt wie ein Aufruf einer Erweiterungsfunktion. Der Funktionsname wird zu einem Namen erweitert, indem die Namensraum-Deklarationen des Evaluierungskontexts verwendet werden.

Falls ein XSLT-Prozessor keine Implementierung einer Erweiterungsfunktion eines speziellen Namens zur Verfügung stellt, muss die function-available-Funktion für den Namen false zurückliefern. Falls eine solche Erweiterungsfunktion in einem Ausdruck auftritt und die Erweiterungsfunktion wirklich aufgerufen wird, muss der XSLT-Prozessor einen Fehler anzeigen. Ein XSLT-Prozessor darf keinen Fehler anzeigen, bloß weil ein Ausdruck eine Erweiterungsfunktion enthält, für die keine Implementierung verfügbar ist.

Falls ein XSLT-Prozessor über eine Implementierung einer Erweiterungsfunktion eines speziellen Namens verfügt, muss die function-available-Funktion für diesen Namen true zurückliefern. Falls eine solche Erweiterung aufgerufen wird, muss der XSLT-Prozessor die Implementierung aufrufen und die Argumente des Funktionsaufrufs übergeben; das Ergebnis, das von der Implementierung zurückgeliefert wird, wird als Ergebnis des Funktionsaufrufs zurückgegeben.

15 Rückgriff

<!-- Kategorie: instruction -->
<xsl:fallback
>
<!-- Inhalt: template -->
</xsl:fallback

Normalerweise bewirkt die Instanziierung eines xsl:fallback-Elements nichts. Falls ein XSLT-Prozessor aber einen Rückgriff für ein Anweisungselement durchführt, muss, falls das Anweisungselement ein oder mehrere xsl:fallback-Kinder besitzt, der Inhalt jedes der xsl:fallback-Kinder der Reihe nach instanziiert werden; anderenfalls muss ein Fehler angezeigt werden. Der Inhalt eines xsl:fallback-Elements ist ein Template.

Die folgenden Funktionen können mit den xsl:choose- und xsl:if-Anweisungen verwendet werden, um explizit zu kontrollieren, wie ein Stylesheet sich verhalten sollte, falls spezielle Elemente oder Funktionen nicht verfügbar sind.

boolean element-available( , string )

Das Argument muss sich zu einer Zeichenkette, die ein QName ist, auswerten lassen. Der QName wird zu einem erweiterten Namen unter Benutzung der Namensraum-Deklarationen im Bereich für den Ausdruck erweitert.

Die element-available-Funktion gibt true zurück, wenn und nur wenn der erweiterte Name der Name einer Anweisung ist. Falls der erweiterte Name einen Namensraum-URI besitzt, der mit dem XSLT-Namensraum-URI übereinstimmt, bezieht er sich auf ein von XSLT definiertes Element. Anderenfalls bezieht er sich auf ein Erweiterungselement. Falls der erweiterte Name einen Null-Namensraum-URI hat, liefert die element-available-Funktion false zurück.

boolean function-available( , string )

Das Argument muss sich zu einer Zeichenkette auswerten lassen, die ein QName ist. Der QName wird zu einem erweiterten Namen unter Benutzung der Namensraum-Deklarationen im Bereich für den Ausdruck erweitert. Die function-available-Funktion gibt true zurück, wenn und nur wenn der erweiterte Name der Name einer Funktion in der Funktionsbibliothek ist. Falls der erweiterte Name einen von Null verschiedenen Namensraum-URI besitzt, bezieht er sich auf eine Erweiterungsfunktion; anderenfalls bezieht er sich auf eine durch XPath oder XSLT definierte Funktion.

16 Ausgabe

<!-- Kategorie: top-level-element -->
<xsl:output
method = | "xml" | "html" | "text" | qname-but-not-ncname
version = | nmtoken
encoding = | string
omit-xml-declaration = | "yes" | "no"
standalone = | "yes" | "no"
doctype-public = | string
doctype-system = | string
cdata-section-elements = | qnames
indent = | "yes" | "no"
media-type = | string
/>

Ein XSLT-Prozessor kann, obwohl es nicht gefordert ist, dazu in der Lage sein (siehe 17 Konformität), den Ergebnisbaum als Folge von Bytes auszugeben. Das xsl:output-Element erlaubt es Stylesheet-Autoren, anzugeben, wie der Ergebnisbaum ausgegeben werden soll. Falls ein XSLT-Prozessor den Ergebnisbaum ausgibt, sollte er dies wie vom xsl:output-Element spezifiziert tun; es ist jedoch nicht gefordert, dies zu tun.

Das xsl:output-Element ist nur als Element der obersten Ebene erlaubt.

Das method-Attribut in xsl:output gibt die generelle Methode an, die für die Ausgabe des Ergebnisbaums verwendet werden soll. Der Wert muss ein QName sein. Falls der QName kein Präfix hat, gibt er eine Methode an, die in diesem Dokument spezifiziert ist, und muss xml, html oder text lauten. Falls der QName ein Präfix hat, wird der QName zu einem erweiterten Namen erweitert, wie in 2.4 Qualifizierte Namen beschrieben; der erweiterte Name gibt die Ausgabemethode an; in diesem Fall wird das Verhalten nicht in diesem Dokument spezifiziert.

Die Vorgabe für das method-Attribut wird wie folgt gewählt. Falls

dann ist als Vorgabe die Ausgabemethode html; anderenfalls ist die Vorgabe-Ausgabemethode xml. Die Vorgabe-Ausgabemethode sollte verwendet werden, wenn keine xsl:output-Elemente vorhanden sind oder falls keines der xsl:output-Elemente einen Wert für das method-Attribut angibt.

Die anderen Attribute von xsl:output stellen Parameter für die Ausgabemethode zur Verfügung. Die folgenden Attribute sind erlaubt:

Die detaillierte Semantik jedes Attributs wird im Folgenden separat für jede Ausgabemethode beschrieben, für die es jeweils anwendbar ist. Falls die Semantik eines Attributs für eine Ausgabemethode nicht beschrieben wird, ist es für die jeweilige Ausgabemethode nicht anwendbar.

Ein Stylesheet darf mehrere xsl:output-Elemente enthalten und darf Stylesheets inkludieren oder importieren, die ebenfalls xsl:output-Elemente enthalten. Alle xsl:output-Elemente, die in einem Stylesheet auftreten, werden in einem einzelnen wirksamen xsl:output-Element vereinigt. Für die cdata-section-elements-Attribute ist der wirksame Wert die Vereinigung der angegebenen Werte. Für die anderen Attribute ist der wirksame Wert derjenige angegebene Wert mit der höchsten Importpriorität. Es ist ein Fehler, falls mehr als ein solcher Wert für ein Attribut vorhanden ist. Ein XSLT-Prozessor darf den Fehler anzeigen; falls er den Fehler nicht anzeigt, sollte er mit der Verwendung des Wertes fortfahren, der zuletzt im Stylesheet vorkommt. Die Werte der Attribute werden mit den Vorgaben versehen, nachdem die xsl:output-Elemente zusammengeführt wurden; unterschiedliche Ausgabemethoden können unterschiedliche Vorgabewerte für ein Attribut haben.

16.1 XML-Ausgabemethode

Die xml-Ausgabemethode gibt den Ergebnisbaum als extern und allgemein analysiertes Entity in wohlgeformtem XML aus. Falls der Wurzelknoten des Ergebnisbaums ein einzelnes Elementknoten-Kind und keine Textknoten-Kinder besitzt, sollte das Entity ebenfalls ein wohlgeformtes XML-Dokument-Entity sein. Falls das Entity innerhalb einer einfachen XML-Dokumenth?ie dieser

<!DOCTYPE doc [
<!ENTITY e SYSTEM "entity-URI">
]>
<doc>&e;</doc>

referenziert wird, in der entity-URI ein URI für das Entity ist, sollte das Hüllendokument als Ganzes ein wohlgeformtes XML-Dokument sein, das zur XML-Namensraum-Empfehlung [XML Names] konform ist. Zusätzlich sollte die Ausgabe so geartet sein, dass wenn ein neuer Baum konstruiert wird, indem die Hülle – wie in 3 Datenmodell beschrieben – als ein XML-Dokument analysiert und anschließend das Dokumentelement entfernt wird, was seine Kinder stattdessen zu Kindern des Wurzelknotens macht, der neue Baum der gleiche wie der Ergebnisbaum sein würde, mit den folgenden möglichen Ausnahmen:

  • Die Reihenfolge der Attribute in den beiden Bäumen kann unterschiedlich sein.

  • Der neue Baum kann Namensraumknoten enthalten, die im Ergebnisbaum nicht vorhanden waren.

    Anmerkung:

    Für einen XSLT-Prozessor kann es notwendig sein, Namensraum-Deklarationen im Zuge der Ausgabe des Ergebnisbaums als XML hinzuzufügen.

Falls ein XSLT-Prozessor eine Dokumenttyp-Deklaration auf Grund des doctype-system-Attributs generiert, beziehen sich die oben genannten Anforderungen auf das Entity, bei dem die generierte Dokumenttyp-Definition entfernt wurde.

Das version-Attribut gibt die XML-Version an, die für die Ausgabe des Ergebnisbaums verwendet werden soll. Falls der XSLT-Prozessor diese XML-Version nicht unterstützt, sollte er eine XML-Version verwenden, die er unterstützt. Die Versionsausgabe in der XML-Deklaration (falls eine XML-Deklaration ausgegeben wird) sollte zu der XML-Version korrespondieren, die der Prozessor für die Ausgabe des Ergebnisbaums verwendet. Der Wert des version-Attributs sollte der VersionNum-Produktion der XML-Empfehlung [XML] genügen. Der Vorgabewert ist 1.0.

Das encoding-Attribut gibt die bevorzugte Kodierung an, die für die Ausgabe des Ergebnisbaums verwendet wird. XSLT-Prozessoren müssen die Werte UTF-8 und UTF-16 beachten. Bei anderen Werten darf der XSLT-Prozessor einen Fehler anzeigen, falls er die angegebene Kodierung nicht unterstützt; falls er keine Fehler anzeigt, sollte er stattdessen UTF-8 oder UTF-16 verwenden. Der XSLT-Prozessor darf keine Kodierung verwenden, deren Name nicht zu der EncName-Produktion der XML-Empfehlung passt [XML]. Falls kein encoding-Attribut angegeben ist, sollte der XSLT-Prozessor entweder UTF-8 oder UTF-16 verwenden. Es ist möglich, dass der Ergebnisbaum ein Zeichen enthalten wird, das nicht in der gewählten Kodierung dargestellt werden kann, die der XSLT-Prozessor für die Ausgabe verwendet. In diesem Fall sollte das Zeichen als Zeichenreferenz ausgegeben werden, falls das Zeichen in einem Kontext vorkommt, in dem XML Zeichenreferenzen erkennt (d.h. innerhalb des Wertes eines Attribut- oder Textknotens); anderenfalls (zum Beispiel, falls das Zeichen im Namen eines Elements auftritt) sollte der XSLT-Prozessor einen Fehler anzeigen.

Wenn das indent-Attribut den Wert yes hat, darf die xml-Ausgabemethode Leerraum als Zusatz zu dem Leerraum im Ergebnisbaum ausgeben (möglicherweise basierend auf dem Leerraum, der aus dem Quelldokument oder dem Stylesheet entfernt wurde), um eine schöne Einrückung beim Ergebnis zu erzielen; falls das indent-Attribut den Wert no hat, sollte es keinen zusätzlichen Leerraum ausgeben. Der Vorgabewert ist no. Die xml-Ausgabemethode sollte einen Algorithmus zur Ausgabe zusätzlichen Leerraums verwenden, der sicherstellt, dass das Ergebnis – falls Leerräume aus der Ausgabe unter Verwendung des in 3.4 Entfernen von Leerräumen beschriebenen Prozesses entfernt werden und falls xsl:text als einziges Element der Menge von Leerraum erhaltenden Elementen vorkommt – falls zusätzlicher Leerraum ausgegeben wird, das gleiche wäre, als wenn zusätzlicher Leerraum nicht ausgegeben würde.

Anmerkung:

Es ist üblicherweise nicht sicher, indent="yes" mit Dokumenttypen zu verwenden, die Elementtypen mit gemischtem Inhalt beinhalten.

Das cdata-section-elements-Attribut enthält eine durch Leerraum getrennte Liste von QNamen. Jeder QName wird zu einem erweiterten Namen erweitert unter Verwendung der Namensraum-Deklarationen bezüglich des xsl:output-Elements, in dem der QName auftritt; falls ein Vorgabe-Namensraum vorhanden ist, wird er für QNamen verwendet, die kein Präfix haben. Die Erweiterung wird vor der Vereinigung von mehreren xsl:output-Elementen in ein einzelnes wirkungsvolles xsl:output-Element ausgeführt. Falls der erweiterte Name des Vaters eines Textknotens ein Mitglied der Liste ist, sollte der Textknoten als CDATA-Absatz ausgegeben werden. Zum Beispiel würde

<xsl:output cdata-section-elements="example"/>

bei einem literalen Ergebniselement, das im Stylesheet als

<example>&lt;foo></example>

oder als

<example><![CDATA[<foo>]]></example>

geschrieben würde, eine Ausgabe von

<example><![CDATA[<foo>]]></example>

zur Folge haben.

Wenn der Textknoten die Zeichensequenz ]]> enthält, dann sollte die gerade offene CDATA-Sektion hinter dem ]] geschlossen werden und eine neue CDATA-Sektion vor dem > geöffnet werden. Zum Beispiel ein literales Ergebniselement, in einem Stylesheet als

<example>]]&gt;</example>

geschrieben, würde ausgegeben als:

<example><![CDATA[]]]]><![CDATA[>]]></example>

Wenn der Textknoten ein Zeichen enthält, das nicht in der Zeichenkodierung repräsentiert werden kann, die zur Ausgabe des Ergebnisbaums benutzt wird, sollte die gerade offene CDATA-Sektion vor diesem Zeichen geschlossen werden. Das Zeichen sollte unter Benutzung einer Zeichenreferenz oder einer Entity-Referenz ausgegeben werden und eine neue CDATA-Sektion sollte für weitere Zeichen in dem Textknoten geöffnet werden.

CDATA-Sektionen sollten nicht benutzt werden, ausgenommen Textknoten, bei denen das cdata-section-elements-Attribut explizit spezifiziert, dass sie mit CDATA-Sektionen ausgegeben werden sollen.

Die xml-Ausgabemethode sollte eine XML-Deklaration ausgeben, außer wenn das omit-xml-declaration-Attribut den Wert yes hat. Die XML-Deklaration sollte sowohl die Versionsinformation als auch die Kodierungs-Deklaration enthalten. Wenn das standalone-Attribut spezifiert ist, sollte es eine eigenständige Dokument-Deklaration mit dem gleichen Wert wie der Wert des standalone-Attributs einfügen. Anderenfalls sollte es keine eigenständige Dokument-Deklaration einfügen; dies stellt sicher, dass es sowohl eine XML-Deklaration (erlaubt am Anfang eines Dokument-Entitys) und eine Text-Deklaration (erlaubt am Anfang eines extern analysierten Entitys) ist.

Wenn das doctype-system-Attribut spezifiziert ist, sollte die xml-Ausgabemethode eine Dokumenttyp-Deklaration unmittelbar vor dem ersten Element ausgeben. Der dem <!DOCTYPE folgende Name sollte der Name des ersten Elements sein. Wenn das doctype-public-Attribut ebenfalls spezifiziert ist, dann sollte die xml-Ausgabemethode PUBLIC ausgeben gefolgt vom öffentlichen Identifikator und dann dem System-Identifikator; anderenfalls sollte es SYSTEM, gefolgt vom System-Identifikator ausgeben. Die interne Untermenge sollte leer sein. Das doctype-public-Attribut sollte ignoriert werden, außer das doctype-system-Attribut ist spezifiziert.

Das media-type-Attribut ist für die xml-Ausgabemethode ma?eblich. Der vorgegebene Wert für das media-type-Attribut ist text/xml.

16.2 HTML-Ausgabemethode

Die html-Ausgabemethode gibt den Ergebnisbaum als HTML aus; zum Beispiel:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="html"/>

<xsl:template match="/">
  <html>
   <xsl:apply-templates/>
  </html>
</xsl:template>

...

</xsl:stylesheet>

Das version-Attribut gibt die HTML-Version an. Der Vorgabewert ist 4.0, was angibt, dass das Ergebnis als HTML entsprechend der HTML 4.0-Empfehlung [HTML] ausgegeben werden sollte.

Die html-Ausgabemethode sollte ein Element nicht abweichend von der xml-Ausgabemethode ausgeben, sofern der erweiterte Name des Elements keinen Null-Namensraum-URI hat; ein Element, dessen erweiterter Name einen Nicht Null-Namensraum-URI hat, sollte als XML ausgegeben werden. Falls der erweiterte Name des Elements einen Null-Namensraum-URI hat, aber der lokale Teil des erweiterten Namens nicht als Name eines HTML-Elements erkannt wird, sollte das Element in der gleichen Weise wie ein nicht leeres Inline-Element ausgegeben werden, wie z.B. span.

Die html-Ausgabemethode sollte für leere Elemente kein Ende-Tag ausgeben. In HTML 4.0 sind die leeren Elemente area, base, basefont, br, col, frame, hr, img, input, isindex, link, meta und param. Zum Beispiel sollte ein Element, das im Stylesheet als <br/> oder <br></br> geschrieben wird, als <br> ausgegeben werden.

Die html-Ausgabemethode sollte die Namen von HTML-Elementen unabhängig von Groß- und Kleinschreibung erkennen. Zum Beispiel sollten Elemente wie br, BR oder Br alle als das HTML br-Element erkannt und ohne Ende-Tag ausgegeben werden.

Die html-Ausgabemethode sollte den Inhalt der script- und style-Elemente nicht schützen (escapen). Zum Beispiel sollte ein literales Ergebniselement in einem Stylesheet wie

<script>if (a &lt; b) foo()</script>

oder

<script><![CDATA[if (a < b) foo()]]></script>

als

<script>if (a < b) foo()</script>

ausgegeben werden.

Die html-Ausgabemethode sollte <-Zeichen, die in Attributwerten auftreten, nicht schützen (escapen).

Falls das indent-Attribut den Wert yes hat, darf die html-Ausgabemethode bei der Ausgabe des Ergebnisbaums Leerraum hinzufügen oder löschen, solange dies nichts daran ändert, wie ein HTML-Benutzeragent die Ausgabe darstellen würde. Der Vorgabewert ist yes.

Die html-Ausgabemethode sollte Nicht-ASCII-Zeichen in URI-Attributwerten unter Verwendung der in der HTML 4.0-Empfehlung Abschnitt B.2.1 empfohlenen Methode schützen (escapen).

Die html-Ausgabemethode darf ein Zeichen unter Verwendung einer Zeichen-Entity-Referenz ausgeben, falls eine solche für das Zeichen in der Version von HTML definiert ist, die von der Ausgabemethode verwendet wird.

Die html-Ausgabemethode sollte die Verarbeitung von Instruktionen mit > anstatt mit ?> beenden.

Die html-Ausgabemethode sollte Boolesche Attribute (das sind Attribute mit nur einem einzelnen erlaubten Wert, der mit dem Namen des Attributs übereinstimmt) in minimierter Form ausgeben. Zum Beispiel sollte ein Start-Tag, das im Stylesheet als

<OPTION selected="selected">

angegeben wird, als

<OPTION selected>

ausgegeben werden.

Die html-Ausgabemethode sollte ein &-Zeichen nicht schützen (escapen), das in einem Attributwert unmittelbar gefolgt von einem {-Zeichen (siehe Abschnitt B.7.1 der HTML 4.0-Empfehlung) auftritt. Zum Beispiel sollte ein Start-Tag, das in einem Stylesheet als

<BODY bgcolor='&amp;{{randomrbg}};'>

geschrieben wird, als

<BODY bgcolor='&{randomrbg};'>

ausgeben werden.

Das encoding-Attribut gibt die bevorzugte zu verwendende Kodierung an. Falls ein HEAD-Element vorhanden ist, sollte die html-Ausgabemethode ein META-Element unmittelbar nach dem Start-Tag des HEAD-Elements hinzufügen, das die Zeichenkodierung angibt, die wirklich verwendet wird. Zum Beispiel:

<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=EUC-JP">
...

Es ist möglich, dass der Ergebnisbaum ein Zeichen enthalten wird, das nicht in der Kodierung dargestellt werden kann, die der XSLT-Prozessor für die Ausgabe verwendet. In diesem Fall sollte das Zeichen, falls es in einem Kontext auftritt, in dem HTML Zeichenreferenzen erkennt, als eine Zeichen-Entity-Referenz oder als dezimal-nummerische Zeichenreferenz ausgegeben werden; anderenfalls (zum Beispiel in einem script- oder style-Element oder in einem Kommentar) sollte der XSLT-Prozessor einen Fehler anzeigen.

Falls die doctype-public- oder doctype-system-Attribute angegeben sind, sollte die html-Ausgabemethode eine Dokumenttyp-Deklaration unmittelbar vor dem ersten Element ausgeben. Der Name, der <!DOCTYPE folgt, sollte HTML oder html sein. Falls das doctype-public-Attribut angegeben ist, sollte die Ausgabemethode PUBLIC – gefolgt von dem angegebenen öffentlichen Bezeichner – ausgeben; falls das doctype-system-Attribut ebenfalls angegeben ist, sollte sie auch den angegebenen Systembezeichner nach dem öffentlichen Bezeichner ausgeben. Falls das doctype-system-Attribut angegeben ist, aber das doctype-public-Attribut nicht, sollte die Ausgabemethode SYSTEM – gefolgt von dem angegebenen Systembezeichner – ausgeben.

Das media-type-Attribut ist für die html-Ausgabemethode anwendbar. Der Vorgabewert ist text/html.

16.3 Text-Ausgabemethode

Die text-Ausgabemethode gibt den Ergebnisbaum aus, indem der Zeichenkettenwert von jedem Textknoten im Ergebnisbaum in der Dokumentreihenfolge ohne jeden Schutz (escaping) ausgegeben wird.

Das media-type-Attribut ist für die text-Ausgabemethode anwendbar. Der Vorgabewert für das media-type-Attribut ist text/plain.

Das encoding-Attribut gibt die Kodierung an, welche die text-Ausgabemethode zur Umwandlung der Zeichenfolgen in Byte-Folgen verwenden sollte. Der Vorgabewert ist systemabhängig. Falls der Ergebnisbaum ein Zeichen enthält, das nicht in der Kodierung darstellbar ist, die der XSLT-Prozessor für die Ausgabe verwendet, sollte der XSLT-Prozessor einen Fehler anzeigen.

16.4 Deaktivierung des Ausgabe-Zeichenschutzes

Normalerweise schützt (escaped) die xml-Ausgabemethode & und < (und möglicherweise andere Zeichen) bei der Ausgabe von Textknoten. Dies stellt sicher, dass die Ausgabe wohlgeformtes XML ist. Jedoch ist es manchmal passend, eine Ausgabe erzeugen zu können, die beinahe, aber nicht völlig wohlgeformtes XML ist; zum Beispiel kann die Ausgabe schlecht geformte Abschnitte enthalten, deren Umwandlung in wohlgeformtes XML mit Hilfe von einem nicht XML-fähigen Folgeprozess geplant ist. Zu diesem Zweck stellt XSLT einen Mechanismus zur Verfügung, um den Ausgabe-Zeichenschutz zu deaktivieren. Ein xsl:value-of- oder xsl:text-Element darf ein disable-output-escaping-Attribut besitzen; erlaubte Werte sind yes oder no; die Vorgabe ist no; falls der Wert yes ist, sollte ein Textknoten, der durch eine Instanziierung eines xsl:value-of- oder xsl:text-Elements erzeugt wurde, ohne jeglichen Schutz ausgegeben werden. Zum Beispiel sollte

<xsl:text disable-output-escaping="yes">&lt;</xsl:text>

das einzelne Zeichen < erzeugen.

Es ist ein Fehler, den Ausgabe-Zeichenschutz für einen Textknoten zu deaktivieren, der für etwas anderes als einen Textknoten im Ergebnisbaum verwendet wird. Folglich ist es ein Fehler, den Ausgabe-Zeichenschutz für ein xsl:value-of- oder xsl:text-Element zu deaktivieren, das zur Erzeugung des Zeichenkettenwerts eines Kommentars, einer Verarbeitungsanweisung oder eines Attributknotens verwendet wird; es ist ebenfalls ein Fehler, ein Ergebnisbaum-Fragment zu einer Zahl oder einer Zeichenkette zu wandeln, wenn das Ergebnisbaum-Fragment einen Textknoten enthält, für den der Zeichenschutz deaktiviert war. In beiden Fällen darf ein XSLT-Prozessor einen Fehler anzeigen; falls er keinen Fehler anzeigt, muss er weiterarbeiten, indem er das disable-output-escaping-Attribut ignoriert.

Das disable-output-escaping-Attribut darf sowohl mit der html-Ausgabemethode als auch mit der xml-Ausgabemethode verwendet werden. Die text-Ausgabemethode ignoriert das disable-output-escaping-Attribut, da sie keinen Ausgabe-Zeichenschutz durchführt.

Ein XSLT-Prozessor wird nur dann den Ausgabe-Zeichenschutz deaktivieren können, wenn er die Ausgabe des Ergebnisbaums kontrolliert. Dies mag nicht immer der Fall sein. Zum Beispiel kann der Ergebnisbaum als Quellbaum für eine weitere XSLT-Transformation anstatt als Ausgabe verwendet werden. Die Unterstützung der Deaktivierung des Ausgabe-Zeichenschutzes wird von einem XSLT-Prozessor nicht gefordert. Falls ein xsl:value-of oder xsl:text angibt, dass der Ausgabe-Zeichenschutz deaktiviert werden sollte und der XSLT-Prozessor dies nicht unterstützt, darf der XSLT-Prozessor einen Fehler anzeigen; falls er keinen Fehler anzeigt, muss er weiterarbeiten, indem er den Ausgabe-Zeichenschutz nicht deaktiviert.

Falls der Ausgabe-Zeichenschutz für ein Zeichen deaktiviert ist, das nicht in der Kodierung repräsentierbar ist, die der XSLT-Prozessor für die Ausgabe verwendet, darf der XSLT-Prozessor einen Fehler anzeigen; falls er keinen Fehler anzeigt, muss er weiterarbeiten, indem er den Ausgabe-Zeichenschutz nicht deaktiviert.

Da die Deaktivierung des Ausgabe-Zeichenschutzes nicht mit allen XSLT-Prozessoren funktionieren mag und in nicht wohlgeformtem XML resultieren kann, sollte sie nur verwendet werden, wenn es keine Alternative gibt.

17 Konformität

Ein sich konform verhaltender XSLT-Prozessor muss in der Lage sein, ein Stylesheet zur Umwandlung eines Quellbaums in einen Ergebnisbaum zu verwenden, wie in diesem Dokument spezifiziert. Ein sich konform verhaltender XSLT-Prozessor braucht nicht in der Lage zu sein, das Ergebnis in XML oder in irgendeiner anderen Art auszugeben.

Anmerkung:

Hersteller von XSLT-Prozessoren werden stark dazu angehalten, eine Möglichkeit zur Verfügung zu stellen, um zu verifizieren, dass sich ihr Prozessor konform verhält, indem sie die Ausgabe des Ergebnisbaums in XML erlauben oder indem sie Zugriff auf den Ergebnisbaum durch eine Standard-API wie DOM oder SAX zur Verfügung stellen.

Ein sich konform verhaltender XSLT-Prozessor muss alle Fehler anzeigen, mit Ausnahme derer, für die ein XSLT-Prozessor durch dieses Dokument speziell die Erlaubnis erh?, sie nicht anzuzeigen. Ein sich konform verhaltender XSLT-Prozessor darf nach Fehlern weiterarbeiten, die er anzeigt, braucht dies aber nicht zu tun.

Ein sich konform verhaltender XSLT-Prozessor darf Grenzen für die Verarbeitungsressourcen festlegen, die durch die Verarbeitung eines Stylesheets verwendet werden.

18 Notation

Der Spezifikation jedes von XSLT definierten Elementtyps geht eine Zusammenfassung seiner Syntax in Form eines Modells für Elemente dieses Typs voraus. Die Bedeutung der Notation der Syntax-Zusammenfassung ist wie folgt:

A Referenzen

A.1 Normative Referenzen

XML
World Wide Web Consortium. Extensible Markup Language (XML) 1.0. W3C-Empfehlung. Siehe http://www.edition-w3c.de/TR/1998/REC-xml-19980210. (Siehe )
XML Names
World Wide Web Consortium. Namespaces in XML. W3C-Empfehlung. Siehe http://www.edition-w3c.de/TR/REC-xml-names. (Siehe )
XPath
World Wide Web Consortium. XML Path Language. W3C-Empfehlung. Siehe http://www.edition-w3c.de/TR/xpath. (Siehe )

A.2 Weitere Referenzen

CSS2
World Wide Web Consortium. Cascading Style Sheets, level 2 (CSS2). W3C-Empfehlung. Siehe http://www.edition-w3c.de/TR/1998/REC-CSS2-19980512. (Siehe )
DSSSL
International Organization for Standardization, International Electrotechnical Commission. ISO/IEC 10179:1996. Document Style Semantics and Specification Language (DSSSL). Internationaler Standard. (Siehe )
HTML
World Wide Web Consortium. HTML 4.0 specification. W3C-Empfehlung. Siehe http://www.edition-w3c.de/TR/REC-html40. (Siehe )
IANA
Internet Assigned Numbers Authority. Character Sets. Siehe ftp://ftp.isi.edu/in-notes/iana/assignments/character-sets. (Siehe )
RFC2278
N. Freed, J. Postel. IANA Charset Registration Procedures. IETF RFC 2278. Siehe http://www.ietf.org/rfc/rfc2278.txt. (Siehe )
RFC2376
E. Whitehead, M. Murata. XML Media Types. IETF RFC 2376. Siehe http://www.ietf.org/rfc/rfc2376.txt. (Siehe )
RFC2396
T. Berners-Lee, R. Fielding, and L. Masinter. Uniform Resource Identifiers (URI): Generic Syntax. IETF RFC 2396. Siehe http://www.ietf.org/rfc/rfc2396.txt. (Siehe )
UNICODE TR10
Unicode Consortium. Unicode Technical Report #10. Unicode Collation Algorithm. Unicode technischer Bericht. Siehe http://www.unicode.org/unicode/reports/tr10/index.html. (Siehe )
XHTML
World Wide Web Consortium. XHTML 1.0: The Extensible HyperText Markup Language. W3C-Vorschlag zur Empfehlung. Siehe http://www.edition-w3c.de/TR/xhtml1. (Siehe )
XPointer
World Wide Web Consortium. XML Pointer Language (XPointer). W3C-Arbeitsentwurf. Siehe http://www.edition-w3c.de/TR/xptr. (Siehe )
XML Stylesheet
World Wide Web Consortium. Associating stylesheets with XML documents. W3C-Empfehlung. Siehe http://www.edition-w3c.de/TR/xml-stylesheet. (Siehe )
XSL
World Wide Web Consortium. Extensible Stylesheet Language (XSL). W3C-Arbeitsentwurf. Siehe http://www.edition-w3c.de/TR/WD-xsl. (Siehe )

B Zusammenfassung der Element Syntax

<!-- Kategorie: instruction -->
<xsl:apply-imports
/>

<!-- Kategorie: instruction -->
<xsl:apply-templates
select = node-set-expression
mode = qname >
<!-- Inhalt: ( xsl:sort | xsl:with-param )* -->
</xsl:apply-templates

<!-- Kategorie: instruction -->
<xsl:attribute
name = { qname }
namespace = { uri-reference } >
<!-- Inhalt: , template -->
</xsl:attribute

<!-- Kategorie: top-level-element -->
<xsl:attribute-set
name = qname
use-attribute-sets = qnames >
<!-- Inhalt: xsl:attribute* -->
</xsl:attribute-set

<!-- Kategorie: instruction -->
<xsl:call-template
name = qname >
<!-- Inhalt: xsl:with-param* -->
</xsl:call-template

<!-- Kategorie: Anweisung -->
<xsl:choose
>
<!-- Inhalt: ( xsl:when+ , xsl:otherwise? ) -->
</xsl:choose

<!-- Kategorie: instruction -->
<xsl:comment
>
<!-- Inhalt: , template -->
</xsl:comment

<!-- Kategorie: instruction -->
<xsl:copy
use-attribute-sets = qnames >
<!-- Inhalt: , template -->
</xsl:copy

<!-- Kategorie: Anweisung -->
<xsl:copy-of
select = expression />

<!-- Kategorie: top-level-element -->
<xsl:decimal-format
name = qname
decimal-separator = char
grouping-separator = char
infinity = string
minus-sign = char
NaN = string
percent = char
per-mille = char
zero-digit = char
digit = char
pattern-separator = char />

<!-- Kategorie: instruction -->
<xsl:element
name = { qname }
namespace = { uri-reference }
use-attribute-sets = qnames >
<!-- Inhalt: , template -->
</xsl:element

<!-- Kategorie: instruction -->
<xsl:fallback
>
<!-- Inhalt: , template -->
</xsl:fallback

<!-- Kategorie: Anweisung -->
<xsl:for-each
select = node-set-expression >
<!-- Inhalt: ( xsl:sort* , template ) -->
</xsl:for-each

<!-- Kategorie: Anweisung -->
<xsl:if
test = boolean-expression >
<!-- Inhalt: , Template -->
</xsl:if

<xsl:import
href = uri-reference />

<!-- Kategorie: top-level-element -->
<xsl:include
href = uri-reference />

<!-- Kategorie: top-level-element -->
<xsl:key
name = qname
match = pattern
use = expression />

<!-- Kategorie: instruction -->
<xsl:message
terminate = "yes" | "no" >
<!-- Inhalt: , template -->
</xsl:message

<!-- Kategorie: top-level-element -->
<xsl:namespace-alias
stylesheet-prefix = prefix | "#default"
result-prefix = prefix | "#default" />

<!-- Kategorie: instruction -->
<xsl:number
level = "single" | "multiple" | "any"
count = pattern
from = pattern
value = number-expression
format = { string }
lang = { nmtoken }
letter-value = { "alphabetic" | "traditional" }
grouping-separator = { char }
grouping-size = { number } />

<xsl:otherwise
>
<!-- Inhalt: Template -->
</xsl:otherwise

<!-- Kategorie: top-level-element -->
<xsl:output
method = "xml" | "html" | "text" | qname-but-not-ncname
version = nmtoken
encoding = string
omit-xml-declaration = "yes" | "no"
standalone = "yes" | "no"
doctype-public = string
doctype-system = string
cdata-section-elements = qnames
indent = "yes" | "no"
media-type = string />

<!-- Kategorie: top-level-element -->
<xsl:param
name = qname
select = expression >
<!-- Inhalt: , template -->
</xsl:param

<!-- Kategorie: top-level-element -->
<xsl:preserve-space
elements = tokens />

<!-- Kategorie: instruction -->
<xsl:processing-instruction
name = { ncname } >
<!-- Inhalt: , template -->
</xsl:processing-instruction

<xsl:sort
select = string-expression
lang = { nmtoken }
data-type = { "text" | "number" | qname-but-not-ncname }
order = { "ascending" | "descending" }
case-order = { "upper-first" | "lower-first" } />

<!-- Kategorie: top-level-element -->
<xsl:strip-space
elements = tokens />

<xsl:stylesheet
id = id
extension-element-prefixes = tokens
exclude-result-prefixes = tokens
version = number >
<!-- Inhalt: ( xsl:import* , top-level-elements ) -->
</xsl:stylesheet

<!-- Kategorie: top-level-element -->
<xsl:template
match = pattern
name = qname
priority = number
mode = qname >
<!-- Inhalt: ( xsl:param* , template ) -->
</xsl:template

<!-- Kategorie: instruction -->
<xsl:text
disable-output-escaping = "yes" | "no" >
<!-- Inhalt: #PCDATA -->
</xsl:text

<xsl:transform
id = id
extension-element-prefixes = tokens
exclude-result-prefixes = tokens
version = number >
<!-- Inhalt: ( xsl:import* , top-level-elements ) -->
</xsl:transform

<!-- Kategorie: instruction -->
<xsl:value-of
select = string-expression
disable-output-escaping = "yes" | "no" />

<!-- Kategorie: top-level-element -->
<!-- Kategorie: instruction -->
<xsl:variable
name = qname
select = expression >
<!-- Inhalt: , template -->
</xsl:variable

<xsl:when
test = boolean-expression >
<!-- Inhalt: , Template -->
</xsl:when

<xsl:with-param
name = qname
select = expression >
<!-- Inhalt: , template -->
</xsl:with-param

C DTD-Fragment für XSLT Stylesheets (Nicht normativ)

Anmerkung:

Dieses DTD-Fragment ist nicht normativ, da XML-1.0-DTDs keine XML-Namensräume unterstützen und folglich die erlaubten Strukturen eines XSLT-Stylesheets nicht korrekt beschreiben können.

Das folgende Entity kann für die Konstruktion einer DTD für XSLT-Stylesheets verwendet werden, die Instanzen einer speziellen Ergebnis-DTD erzeugen. Vor der Referenzierung des Entitys muss die Stylesheet-DTD ein result-elements-Parameter-Entity definieren, das die erlaubten Ergebniselementtypen auflistet. Zum Beispiel:

<!ENTITY % result-elements "
  | fo:inline-sequence
  | fo:block
">

Solche Ergebniselemente sollten so deklariert sein, dass sie xsl:use-attribute-sets- und xsl:extension-element-prefixes-Attribute besitzen. Das folgende Entity deklariert zu diesem Zweck den result-element-atts-Parameter. Der Inhalt, den XSLT für Ergebniselemente erlaubt, ist der gleiche, den es für die XSLT-Elemente erlaubt, die in dem folgenden Entity mit dem Inhaltsmodell %template; deklariert sind. Die DTD darf ein restriktiveres Inhaltsmodell als %template; verwenden, um die Beschränkungen der Ergebnis-DTD widerzuspiegeln.

Die DTD darf das non-xsl-top-level-Parameter-Entity definieren, um zusätzliche Elemente auf oberster Ebene für sich vom XSLT-Namensraum unterscheidende Namensräume zu erlauben.

Die Verwendung des xsl:-Präfixes in dieser DTD impliziert nicht, dass die Verwendung dieses Präfixes für XSLT-Stylesheets notwendig ist. Jedes der in dieser DTD deklarierten Elemente darf, im Zusatz zu den in dieser DTD deklarierten Attributen, Attribute besitzen, deren Namen mit xmlns: beginnt oder gleich xmlns ist.

<!ENTITY % char-instructions "
  | xsl:apply-templates
  | xsl:call-template
  | xsl:apply-imports
  | xsl:for-each
  | xsl:value-of
  | xsl:copy-of
  | xsl:number
  | xsl:choose
  | xsl:if
  | xsl:text
  | xsl:copy
  | xsl:variable
  | xsl:message
  | xsl:fallback
">

<!ENTITY % instructions "
  %char-instructions;
  | xsl:processing-instruction
  | xsl:comment
  | xsl:element
  | xsl:attribute
">

<!ENTITY % char-template "
 (#PCDATA
  %char-instructions;)*
">

<!ENTITY % template "
 (#PCDATA
  %instructions;
  %result-elements;)*
">

<!-- Used for the type of an attribute value that is a URI reference.-->
<!ENTITY % URI "CDATA">

<!-- Used for the type of an attribute value that is a pattern.-->
<!ENTITY % pattern "CDATA">

<!-- Used for the type of an attribute value that is an
     attribute value template.-->
<!ENTITY % avt "CDATA">

<!-- Used for the type of an attribute value that is a QName; the prefix
     gets expanded by the XSLT processor. -->
<!ENTITY % qname "NMTOKEN">

<!-- Like qname but a whitespace-separated list of QNames. -->
<!ENTITY % qnames "NMTOKENS">

<!-- Used for the type of an attribute value that is an expression.-->
<!ENTITY % expr "CDATA">

<!-- Used for the type of an attribute value that consists
     of a single character.-->
<!ENTITY % char "CDATA">

<!-- Used for the type of an attribute value that is a priority. -->
<!ENTITY % priority "NMTOKEN">

<!ENTITY % space-att "xml:space (default|preserve) #IMPLIED">

<!-- This may be overridden to customize the set of elements allowed
at the top-level. -->

<!ENTITY % non-xsl-top-level "">

<!ENTITY % top-level "
 (xsl:import*,
  (xsl:include
  | xsl:strip-space
  | xsl:preserve-space
  | xsl:output
  | xsl:key
  | xsl:decimal-format
  | xsl:attribute-set
  | xsl:variable
  | xsl:param
  | xsl:template
  | xsl:namespace-alias
  %non-xsl-top-level;)*)
">

<!ENTITY % top-level-atts '
  extension-element-prefixes CDATA #IMPLIED
  exclude-result-prefixes CDATA #IMPLIED
  id ID #IMPLIED
  version NMTOKEN #REQUIRED
  xmlns:xsl CDATA #FIXED "http://www.w3.org/1999/XSL/Transform"
  %space-att;
'>

<!-- This entity is defined for use in the ATTLIST declaration
for result elements. -->

<!ENTITY % result-element-atts '
  xsl:extension-element-prefixes CDATA #IMPLIED
  xsl:exclude-result-prefixes CDATA #IMPLIED
  xsl:use-attribute-sets %qnames; #IMPLIED
  xsl:version NMTOKEN #IMPLIED
'>

<!ELEMENT xsl:stylesheet %top-level;>
<!ATTLIST xsl:stylesheet %top-level-atts;>

<!ELEMENT xsl:transform %top-level;>
<!ATTLIST xsl:transform %top-level-atts;>

<!ELEMENT xsl:import EMPTY>
<!ATTLIST xsl:import href %URI; #REQUIRED>

<!ELEMENT xsl:include EMPTY>
<!ATTLIST xsl:include href %URI; #REQUIRED>

<!ELEMENT xsl:strip-space EMPTY>
<!ATTLIST xsl:strip-space elements CDATA #REQUIRED>

<!ELEMENT xsl:preserve-space EMPTY>
<!ATTLIST xsl:preserve-space elements CDATA #REQUIRED>

<!ELEMENT xsl:output EMPTY>
<!ATTLIST xsl:output
  method %qname; #IMPLIED
  version NMTOKEN #IMPLIED
  encoding CDATA #IMPLIED
  omit-xml-declaration (yes|no) #IMPLIED
  standalone (yes|no) #IMPLIED
  doctype-public CDATA #IMPLIED
  doctype-system CDATA #IMPLIED
  cdata-section-elements %qnames; #IMPLIED
  indent (yes|no) #IMPLIED
  media-type CDATA #IMPLIED
>

<!ELEMENT xsl:key EMPTY>
<!ATTLIST xsl:key
  name %qname; #REQUIRED
  match %pattern; #REQUIRED
  use %expr; #REQUIRED
>

<!ELEMENT xsl:decimal-format EMPTY>
<!ATTLIST xsl:decimal-format
  name %qname; #IMPLIED
  decimal-separator %char; "."
  grouping-separator %char; ","
  infinity CDATA "Infinity"
  minus-sign %char; "-"
  NaN CDATA "NaN"
  percent %char; "%"
  per-mille %char; "&#x2030;"
  zero-digit %char; "0"
  digit %char; "#"
  pattern-separator %char; ";"
>

<!ELEMENT xsl:namespace-alias EMPTY>
<!ATTLIST xsl:namespace-alias
  stylesheet-prefix CDATA #REQUIRED
  result-prefix CDATA #REQUIRED
>

<!ELEMENT xsl:template
 (#PCDATA
  %instructions;
  %result-elements;
  | xsl:param)*
>

<!ATTLIST xsl:template
  match %pattern; #IMPLIED
  name %qname; #IMPLIED
  priority %priority; #IMPLIED
  mode %qname; #IMPLIED
  %space-att;
>

<!ELEMENT xsl:value-of EMPTY>
<!ATTLIST xsl:value-of
  select %expr; #REQUIRED
  disable-output-escaping (yes|no) "no"
>

<!ELEMENT xsl:copy-of EMPTY>
<!ATTLIST xsl:copy-of select %expr; #REQUIRED>

<!ELEMENT xsl:number EMPTY>
<!ATTLIST xsl:number
   level (single|multiple|any) "single"
   count %pattern; #IMPLIED
   from %pattern; #IMPLIED
   value %expr; #IMPLIED
   format %avt; '1'
   lang %avt; #IMPLIED
   letter-value %avt; #IMPLIED
   grouping-separator %avt; #IMPLIED
   grouping-size %avt; #IMPLIED
>

<!ELEMENT xsl:apply-templates (xsl:sort|xsl:with-param)*>
<!ATTLIST xsl:apply-templates
  select %expr; "node()"
  mode %qname; #IMPLIED
>

<!ELEMENT xsl:apply-imports EMPTY>

<!-- xsl:sort cannot occur after any other elements or
any non-whitespace character -->

<!ELEMENT xsl:for-each
 (#PCDATA
  %instructions;
  %result-elements;
  | xsl:sort)*
>

<!ATTLIST xsl:for-each
  select %expr; #REQUIRED
  %space-att;
>

<!ELEMENT xsl:sort EMPTY>
<!ATTLIST xsl:sort
  select %expr; "."
  lang %avt; #IMPLIED
  data-type %avt; "text"
  order %avt; "ascending"
  case-order %avt; #IMPLIED
>

<!ELEMENT xsl:if %template;>
<!ATTLIST xsl:if
  test %expr; #REQUIRED
  %space-att;
>

<!ELEMENT xsl:choose (xsl:when+, xsl:otherwise?)>
<!ATTLIST xsl:choose %space-att;>

<!ELEMENT xsl:when %template;>
<!ATTLIST xsl:when
  test %expr; #REQUIRED
  %space-att;
>

<!ELEMENT xsl:otherwise %template;>
<!ATTLIST xsl:otherwise %space-att;>

<!ELEMENT xsl:attribute-set (xsl:attribute)*>
<!ATTLIST xsl:attribute-set
  name %qname; #REQUIRED
  use-attribute-sets %qnames; #IMPLIED
>

<!ELEMENT xsl:call-template (xsl:with-param)*>
<!ATTLIST xsl:call-template
  name %qname; #REQUIRED
>

<!ELEMENT xsl:with-param %template;>
<!ATTLIST xsl:with-param
  name %qname; #REQUIRED
  select %expr; #IMPLIED
>

<!ELEMENT xsl:variable %template;>
<!ATTLIST xsl:variable 
  name %qname; #REQUIRED
  select %expr; #IMPLIED
>

<!ELEMENT xsl:param %template;>
<!ATTLIST xsl:param 
  name %qname; #REQUIRED
  select %expr; #IMPLIED
>

<!ELEMENT xsl:text (#PCDATA)>
<!ATTLIST xsl:text
  disable-output-escaping (yes|no) "no"
>

<!ELEMENT xsl:processing-instruction %char-template;>
<!ATTLIST xsl:processing-instruction 
  name %avt; #REQUIRED
  %space-att;
>

<!ELEMENT xsl:element %template;>
<!ATTLIST xsl:element 
  name %avt; #REQUIRED
  namespace %avt; #IMPLIED
  use-attribute-sets %qnames; #IMPLIED
  %space-att;
>

<!ELEMENT xsl:attribute %char-template;>
<!ATTLIST xsl:attribute 
  name %avt; #REQUIRED
  namespace %avt; #IMPLIED
  %space-att;
>

<!ELEMENT xsl:comment %char-template;>
<!ATTLIST xsl:comment %space-att;>

<!ELEMENT xsl:copy %template;>
<!ATTLIST xsl:copy
  %space-att;
  use-attribute-sets %qnames; #IMPLIED
>

<!ELEMENT xsl:message %template;>
<!ATTLIST xsl:message
  %space-att;
  terminate (yes|no) "no"
>

<!ELEMENT xsl:fallback %template;>
<!ATTLIST xsl:fallback %space-att;>

D Beispiele (Nicht normativ)

D.1 Dokumentbeispiel

Dieses Beispiel ist ein Stylesheet für die Transformation von Dokumenten, die zu einer einfachen DTD konform sind, in XHTML [XHTML]. Die DTD lautet:

<!ELEMENT doc (title, chapter*)>
<!ELEMENT chapter (title, (para|note)*, section*)>
<!ELEMENT section (title, (para|note)*)>
<!ELEMENT title (#PCDATA|emph)*>
<!ELEMENT para (#PCDATA|emph)*>
<!ELEMENT note (#PCDATA|emph)*>
<!ELEMENT emph (#PCDATA|emph)*>

Das Stylesheet ist:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns="http://www.w3.org/TR/xhtml1/strict">

<xsl:strip-space elements="doc chapter section"/>
<xsl:output
   method="xml"
   indent="yes"
   encoding="iso-8859-1"
/>

<xsl:template match="doc">
 <html>
   <head>
     <title>
       <xsl:value-of select="title"/>
     </title>
   </head>
   <body>
     <xsl:apply-templates/>
   </body>
 </html>
</xsl:template>

<xsl:template match="doc/title">
  <h1>
    <xsl:apply-templates/>
  </h1>
</xsl:template>

<xsl:template match="chapter/title">
  <h2>
    <xsl:apply-templates/>
  </h2>
</xsl:template>

<xsl:template match="section/title">
  <h3>
    <xsl:apply-templates/>
  </h3>
</xsl:template>

<xsl:template match="para">
  <p>
    <xsl:apply-templates/>
  </p>
</xsl:template>

<xsl:template match="note">
  <p class="note">
    <b>ANMERKUNG: </b>
    <xsl:apply-templates/>
  </p>
</xsl:template>

<xsl:template match="emph">
  <em>
    <xsl:apply-templates/>
  </em>
</xsl:template>

</xsl:stylesheet>

Mit dem folgenden Eingabedokument

<!DOCTYPE doc SYSTEM "doc.dtd">
<doc>
<title>Dokumenttitel</title>
<chapter>
<title>Kapiteltitel</title>
<section>
<title>Absatztitel</title>
<para>Dies ist ein Test.</para>
<note>Dies ist eine Anmerkung.</note>
</section>
<section>
<title>Ein weiterer Absatztitel</title>
<para>Dies ist <emph>ein weiterer</emph> Test.</para>
<note>Dies ist ein weiterer Knoten.</note>
</section>
</chapter>
</doc>

würde folgende Ausgabe produziert:

<?xml version="1.0" encoding="iso-8859-1"?>
<html xmlns="http://www.w3.org/TR/xhtml1/strict">
<head>
<title>Dokumenttitel</title>
</head>
<body>
<h1>Dokumenttitel</h1>
<h2>Kapiteltitel</h2>
<h3>Absatztitel</h3>
<p>Dies ist ein Test.</p>
<p class="note">
<b>ANMERKUNG: </b>Dies ist eine Anmerkung.</p>
<h3>Ein weiterer Absatztitel</h3>
<p>Dies ist <em>ein weiterer</em> Test.</p>
<p class="note">
<b>ANMERKUNG: </b>Dies ist eine weitere Anmerkung.</p>
</body>
</html>

D.2 Datenbeispiel

Dies ist ein Beispiel zur Umwandlung von einigen in XML repräsentierten Daten unter Verwendung von drei unterschiedlichen XSLT-Stylesheets, um drei unterschiedliche Repräsentationen der Daten zu produzieren: HTML, SVG und VRML.

Die Eingabedaten sind:

<umsaetze>

        <abteilung id="Norden">
                <ertrag>10</ertrag>
                <wachstum>9</wachstum>
                <bonus>7</bonus>
        </abteilung>

        <abteilung id="Sueden">
                <ertrag>4</ertrag>
                <wachstum>3</wachstum>
                <bonus>4</bonus>
        </abteilung>

        <abteilung id="Westen">
                <ertrag>6</ertrag>
                <wachstum>-1.5</wachstum>
                <bonus>2</bonus>
        </abteilung>

</umsaetze>

Das folgende Stylesheet, das die in 2.3 Literale Ergebniselemente als Stylesheet beschriebene vereinfachte Syntax verwendet, wandelt die Daten in HTML um:

<html xsl:version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      lang="en">
    <head>
	<title>Umsatzergebnisse nach Abteilung</title>
    </head>
    <body>
	<table border="1">
	    <tr>
		<th>Abteilung</th>
		<th>Ertrag</th>
		<th>Wachstum</th>
		<th>Bonus</th>
	    </tr>
	    <xsl:for-each select="umsaetze/abteilung">
		<!-- sortiere das Ergebnis nach dem Ertrag -->
		<xsl:sort select="ertrag"
			  data-type="number"
			  order="descending"/>
		<tr>
		    <td>
			<em><xsl:value-of select="@id"/></em>
		    </td>
		    <td>
			<xsl:value-of select="ertrag"/>
		    </td>
		    <td>
			<!-- kennzeichne negatives Wachstum in rot -->
			<xsl:if test="wachstum &lt; 0">
			     <xsl:attribute name="style">
				 <xsl:text>color:red</xsl:text>
			     </xsl:attribute>
			</xsl:if>
			<xsl:value-of select="wachstum"/>
		    </td>
		    <td>
			<xsl:value-of select="bonus"/>
		    </td>
		</tr>
	    </xsl:for-each>
	</table>
    </body>
</html>

Die HTML-Ausgabe ist:

<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Umsatzergebnisse nach Abteilung</title>
</head>
<body>
<table border="1">
<tr>
<th>Abteilung</th><th>Ertrag</th><th>Wachstum</th><th>Bonus</th>
</tr>
<tr>
<td><em>Norden</em></td><td>10</td><td>9</td><td>7</td>
</tr>
<tr>
<td><em>Westen</em></td><td>6</td><td style="color:red">-1.5</td><td>2</td>
</tr>
<tr>
<td><em>Sueden</em></td><td>4</td><td>3</td><td>4</td>
</tr>
</table>
</body>
</html>

Das folgende Stylesheet wandelt die Daten in SVG um:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns="http://www.w3.org/Graphics/SVG/SVG-19990812.dtd">

<xsl:output method="xml" indent="yes" media-type="image/svg"/>

<xsl:template match="/">

<svg width = "3in" height="3in">
    <g style = "stroke: #000000"> 
        <!-- zeichne die Achsen -->
        <line x1="0" x2="150" y1="150" y2="150"/>
        <line x1="0" x2="0" y1="0" y2="150"/>
        <text x="0" y="10">Ertrag</text>
        <text x="150" y="165">Abteilung</text>
        <xsl:for-each select="umsaetze/abteilung">
	    <!-- definieren einiger sinnvoller Variablen -->

	    <!-- die x Position des Balkens -->
	    <xsl:variable name="pos"
	                  select="(position()*40)-30"/>

	    <!-- die Hoehe des Balkens -->
	    <xsl:variable name="height"
	                  select="ertrag*10"/>

	    <!-- das Rechteck -->
	    <rect x="{$pos}" y="{150-$height}"
                  width="20" height="{$height}"/>

	    <!-- die Textbeschriftung -->
	    <text x="{$pos}" y="165">
	        <xsl:value-of select="@id"/>
	    </text> 

	    <!-- der Wert des Balkens -->
	    <text x="{$pos}" y="{145-$height}">
	        <xsl:value-of select="ertrag"/>
	    </text>
        </xsl:for-each>
    </g>
</svg>

</xsl:template>
</xsl:stylesheet>

Die SVG-Ausgabe ist:

<svg width="3in" height="3in"
     xmlns="http://www.w3.org/Graphics/SVG/svg-19990412.dtd">
    <g style="stroke: #000000">
	<line x1="0" x2="150" y1="150" y2="150"/>
	<line x1="0" x2="0" y1="0" y2="150"/>
	<text x="0" y="10">Ertrag</text>
	<text x="150" y="165">Abteilung</text>
	<rect x="10" y="50" width="20" height="100"/>
	<text x="10" y="165">Norden</text>
	<text x="10" y="45">10</text>
	<rect x="50" y="110" width="20" height="40"/>
	<text x="50" y="165">Sueden</text>
	<text x="50" y="105">4</text>
	<rect x="90" y="90" width="20" height="60"/>
	<text x="90" y="165">Westen</text>
	<text x="90" y="85">6</text>
    </g>
</svg>

Das folgende Stylesheet wandelt die Daten in VRML um:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!-- generiere eine Textausgabe mit dem Mime-Typ model/vrml, verwende den Vorgabezeichensatz -->
<xsl:output method="text" encoding="UTF-8" media-type="model/vrml"/>  

        <xsl:template match="/">#VRML V2.0 utf8 
 
# externproto Definition eines einzelnen Balkensegments
EXTERNPROTO bar [ 
  field SFInt32 x  
  field SFInt32 y  
  field SFInt32 z  
  field SFString name  
  ] 
  "http://www.vrml.org/WorkingGroups/dbwork/barProto.wrl" 
 
# inline beinhaltet die Achsen des Grafen
Inline {  
        url "http://www.vrml.org/WorkingGroups/dbwork/barAxes.wrl" 
        } 
        
                <xsl:for-each select="ertrag/abteilung">
bar {
        x <xsl:value-of select="ertrag"/>
        y <xsl:value-of select="wachstum"/>
        z <xsl:value-of select="bonus"/>
        name "<xsl:value-of select="@id"/>" 
        }
                </xsl:for-each>
        
        </xsl:template> 
 
</xsl:stylesheet>

Die VRML-Ausgabe ist:

#VRML V2.0 utf8 
 
# externproto Definition eines einzelnen Balkensegments
EXTERNPROTO bar [ 
  field SFInt32 x  
  field SFInt32 y  
  field SFInt32 z  
  field SFString name  
  ] 
  "http://www.vrml.org/WorkingGroups/dbwork/barProto.wrl" 
 
# inline beinhaltet die Achsen des Grafen
Inline {  
        url "http://www.vrml.org/WorkingGroups/dbwork/barAxes.wrl" 
        } 
        
                
bar {
        x 10
        y 9
        z 7
        name "Norden" 
        }
                
bar {
        x 4
        y 3
        z 4
        name "Sueden" 
        }
                
bar {
        x 6
        y -1.5
        z 2
        name "Westen" 
        }

E Anerkennungen (Nicht normativ)

Die Nachstehenden haben zur Erstellung dieses Entwurfs beigetragen:

Diese Spezifikation wurde von der W3C XSL Working Group (WG) entwickelt und zur Veröffentlichung zugelassen. Die WG-Zulassung dieser Spezifikation impliziert nicht notwendigerweise, dass alle WG-Mitglieder für die Zulassung gestimmt haben. Die aktuellen Mitglieder der XSL WG sind:

F Änderungen seit der vorgeschlagenen Empfehlung (Nicht normativ)

Im Folgenden finden sich die Änderungen seit der vorgeschlagenen Empfehlung:

G In Erwägung gezogene Fähigkeiten für zukünftige XSLT-Versionen (Nicht normativ)

Die folgenden Fähigkeiten werden für zukünftige Versionen von XSLT nach XSLT 1.0 in Erwägung gezogen:


Weitere Informationen zu den Übersetzern auf den folgenden Webseiten: klute-thiemann.de
Weitere Informationen zur Buchreihe und dem Projekt edition-w3c.de: edition W3C.de