Kapitel 6 XSL - Extensible Stylesheet Language

6.1 Warum XSL? 232

6.2 Cascading Stylesheets (CSS) 240

6.3 Konstruktionsregeln (rules) 247

6.4 Flow Objects 248

6.5 Muster (pattern) 251

6.6 Aktionen (action) 262

6.7 Skriptsprachen 266

6.8 Referenz XSL 275

6.1 Warum XSL?

Im Zuge der Entwicklung von XML erfuhr auch die Stylesheet Sprache, die ursprünglich für HTML entworfen wurde, einige Veränderungen. Die Stylesheet Sprache für XML heißt Extensible Stylesheet Language (kurz XSL). Sie ist den besonderen Erfordernissen von XML angepasst und wandelt die strukturellen oder semantischen Auszeichnungen in visuelle Ausgaben um.

Das folgende XML-Beispiel soll die Problematik noch einmal verdeutlichen:

<geburtsdatum>01.09.1968</geburtsdatum>

Diese so ausgezeichnete Zeile sagt uns zwar, dass es sich bei dem eingeschlossenen Datum um ein Geburtsdatum handelt, sie trifft aber noch keinerlei Aussagen über die Art der Darstellung. In HTML werden in erster Linie physische Markups oder Befehle eingesetzt deren Darstellung durch den Browser vorgegeben wird. Beispielsweise könnten wir definieren, dass unser Geburtsdatum in Fettschrift ausgegeben wird. Die semantische Information ist damit allerdings verloren gegangen.

<B>01.09.1968</B>
<I>01.09.1968</I>

Auch in HTML existieren eine Reihe von semantischen Befehlen, beispielsweise die verschiedenen Überschriften-Ebenen.

<H1>Überschrift 1. Ebene</H1>
<H2>Überschrift 2. Ebene</H2>
<H3>Überschrift 3. Ebene</H3>
<H4>Überschrift 4. Ebene</H4>
<H5>Überschrift 5. Ebene</H5>
<H6>Überschrift 6. Ebene</H6>

Aufgrund der geringen Anzahl von Befehlen und der eindeutigen Definition ist es hier möglich für diese semantischen Tags physische Übersetzungen innerhalb des Browsers festzulegen. Zusätzlich ermöglicht HTML auch mithilfe der CSS eigene Definitionen für die Darstellung der einzelnen Markups zu definieren. Anders als in XML ist diese Definition aber nicht so eminent wichtig wie in HTML.

Sobald wir, wie in XML möglich, eigene Markup-Befehle definieren, kann dem Browser die gewünschte Darstellung nicht mehr bekannt sein. In diesem Fall müssen wir zusätzlich zur semantischen Auszeichnung dem Browser mitteilen, wie er mit den eingesetzten Tags umzugehen hat. Dies geschieht mithilfe einer XSL-Definition.

Die konsequente Durchsetzung der Grundintention, die die Urväter von SGML und XML verfolgten, bedeutet eine klare Trennung von semantischer und physischer Auszeichnung in zwei Dokumente. XML als klare Auszeichnung der semantischen Struktur und XSL als Umsetzung dieser Struktur in eine visuelle Ausgabe.

Abb. 6.25: Trennung zwischen semantischer und physischer Auszeichnung.

Mithilfe der XSL-Definition können XML-Dokumente in andere Dokumenten-Formate konvertiert werden. In erster Linie geschieht diese Konvertierung heute in Richtung HTML, da HTML-Browser die weiteste Verbreitung haben. In der Entwicklung befinden sich aber auch Möglichkeiten zur Umwandlung von XML-Dokumenten in RTF- oder PDF-Formate.

Der Inhalt dieser neu generierten HTML-, RTF- oder PDF-Dokumente entstammt der jeweiligen XML-Datei und die visuelle Umsetzung ist in dem zugehörigen XSL-Stylesheet festgelegt (siehe Abb. 6.2).

Abb. 6.26: Der XSL-Prozessor verbindet XML-Dokument und XSL-Definition zu einem HTML-Dokument.

Die Entwicklung von XSL ist allerdings noch am Anfang und bisher liegt noch keine offiziell vom W3C verabschiedete Definition vor. Ein Firmenkonsortium unter Beteiligung von Microsoft, Inso Cooperation und der Firma ArborText, hat allerdings schon einen Entwurf zu XSL abgegeben, der mit hoher Wahrscheinlichkeit mit nur kleinen Änderungen vom W3C übernommen wird.

Wenn Sie sich von Zeit zu Zeit über den aktuellen Stand der Entwicklung informieren möchten, finden Sie beim W3C die offiziellen Vorschläge zum XSL-Standard:

http://www.w3.org/style/xsl/

Außerdem findet dieser Quasi-Standard natürlich schon eine hohe Akzeptanz allein aufgrund der weiten Verbreitung des Microsoft Internet Explorer. Unsere Ausführungen zu diesem Thema halten sich daher sehr stark an die von Microsoft vorgelegten und vom W3C veröffentlichten Entwürfe. Der Standard befindet sich allerdings immer noch in der Diskussionsphase.

Ähnlich wie für XML wurde auch für XSL vom W3C ein strenger Katalog von Anforderungen an das Design dieser Sprache gestellt. Wir möchten Ihnen die wichtigsten Punkte in Kürze vorstellen:

Insbesondere die Einhaltung der XML-Syntax zur Definition von XSL-Dateien hat den großen Vorteil, dass bestehende XML-Tools zur Erstellung und Validierung eingesetzt werden können.

Grundsätzlich stellt XSL Möglichkeiten zur Veränderung von Elementen der folgenden Arten zur Verfügung:

6.1.1 Document Style Semantics and Specific Language (DSSSL)

Seit 1996 existiert unter SGML bereits die Document Style Semantic and Specific Language (kurz DSSSL). DSSSL ist in der ISO/IEC-Norm 10179 definiert. Dieser Standard übernimmt unter SGML die Aufgabe der Stilauszeichnung. Auch diese Sprache wird Einfluss auf die zukünftige Gestaltung von XSL haben. DSSSL ist allerdings eine wesentlich umfangreichere und weitreichendere Sprache als beispielsweise CSS. DSSSL ist eine echte Programmiersprache, die von einem Lisp-Dialekt abgeleitet ist. Neben reinen Stilkomponenten fördert DSSSL wesentlich stärker die dynamischen Elemente einer Website. Obwohl als ISO-Standard verabschiedet, findet DSSSL heute aufgrund der sehr hohen Komplexität sehr wenig Unterstützung durch passende Software-Produkte.

DSSSL legt einige Komponenten fest, die wir in diesem Kapitel aufgreifen:

Detaillierte Informationen zu DSSSL finden Sie im Internet unter:

http://www.jclark.com/dsssl

Erste Entwürfe von XSL waren anfangs noch wesentlich stärker durch DSSSL beeinflusst. XSL basiert ursprünglich auf einer Untermenge des DSSSL-Standards. Die aktuellen Entwürfe von Microsoft, die sich bereits heute einer breiten Zustimmung erfreuen, tendieren aber stärker in eine weniger komplexe und weniger leistungsfähige Sprache.

6.1.2 Einsatz von CSS unter XML

Die aus HTML bekannten Cascading Stylesheet können auch unter XML eingesetzt werden. Gerade in der neu vorgelegten Version 2.0 des CSS-Standards wurden schon einige Veränderungen speziell im Bezug auf XML eingearbeitet.

Die Funktionsvielfalt von CSS beschränkt sich allerdings auf minimale Veränderungen an einzelnen Elementen. Für definierte Markups in XML können mithilfe von CSS bestimmte physische Charakteristika vorgegeben werden. Aber es ist noch nicht möglich einzelne Elemente in eine komplexere Struktur von Objekten zu integrieren.

Zwar können zusätzlich zu bereits existierenden Befehlen neue Instanzen hinzugefügt werden, gerade in Bezug auf die viel stärker geforderte Interaktivität einzelner Elemente und der dynamischen Website-Programmierung reicht CSS bei weitem nicht aus.

So ist es mithilfe von CSS noch nicht einmal möglich, die in jeder noch so einfachen Textverarbeitung bekannte Funktion der automatischen Seiten- und Kapitelnummerierung, automatischer Erstellung von Inhaltsverzeichnissen oder feste Kopf- und Fußzeilen zu realisieren.

XSL unterstützt die meisten Funktionen, die auch aus CSS bekannt sind, daher ist eine leichte Konvertierung von Cascading Stylesheets in die Extensible Stylesheet Language ohne größere manuelle Nacharbeit möglich.

6.1.3 Der Microsoft XSL Parser

Microsoft hat zum Thema XSL einen kleinen Parser veröffentlicht, den wir gut für unsere nächsten Beispiele verwenden können. Mit dem einfachen Kommandozeilen-Tool lassen sich mit einer XML-Datei in Verbindung mit einer XSL-Definition HTML Dateien erzeugen.

Damit der Microsoft XSL-Parser problemlos läuft, muss auf dem Rechner der Microsoft Internet Explorer in der Version 4.0 oder 5.0 installiert sein.

Eine aktuelle Version des Programms MSXSL erhalten Sie auf der Microsoft Homepage im Internet unter:

http://www.microsoft.com/xml/xsl/

An unseren Beispielen wird deutlich, warum ausgerechnet XSL so eminent wichtig für die Verbreitung von XML ist. Denn bisher existieren keine Browser, die XML-Dokumente anzeigen können. Und auch mit Blick auf die Zukunft wird es schwierig solche Programme zu erstellen, die gleichzeitig XML-Dokument, Document Type Definition und eventuelle Stylesheets berücksichtigen.

Daher wird der kurz und mittelfristige Weg der sein, dass Dokumente zwar in XML erzeugt werden, dann aber in ein anderes Format, vorzugsweise HTML, konvertiert werden müssen. Diese HTML-Dateien lassen sich auch mit den heute verbreiteten Standardbrowsern problemlos anzeigen.

Abb. 6.27: Der MSXSL-Parser arbeitet als Kommandozeilen-Tool unter MS-DOS.

Drei Parameter sind dem Microsoft XML-Parser zu übergeben:

Parameter Bedeutung
-i
Die Eingabedatei, üblicherweise ein XML-Dokument.
-s
Eine Stylesheet-Definition (das XSL-File).
-o
Der Name der Ausgabedatei, die im HTML-Format erstellt wird.

Starten Sie den Konvertierungsvorgang mit den beiliegenden Beispielen über die Kommandozeileneingabe in einem MS-DOS-Fenster:

msxsl -i sample.xml -s sample.xsl -o sample.html

Abb. 6.28: Start des Übersetzungsvorgangs perEingabezeile.

Die folgenden drei Beispiele verdeutlichen, wie mithilfe eines einzigen XML-Dokument auf das verschiedene XSL-Stylesheets angewendet wurden, drei völlig verschiedene HTML-Ausgabedokumente erzeugt wurden. Das heißt die gleichen Daten können ohne großen Aufwand und ohne Änderung an der semantischen Struktur verschiedenartig dargestellt werden.

Hier liegt eine der ganz großen Stärken von XML in Verbindung mit XSL. Für verschiedene Sichtweisen auf die gleichen Daten ist keine Änderung der Daten selbst mehr notwendig. Man wendet einfach ein anderes Stylesheet auf das Dokument an. Die Trennung von Semantik und Visualisierung wird hier in Reinkultur deutlich.

Die Beispiele basieren alle auf der XML-Datei sample.xml:

msxsl -i sample.xml -s hlist.xsl -o sample.html

Abb. 6.29: Dieses Beispiel wurde mit der Datei hlist.xsl erzeugt.

msxsl -i sample.xml -s alternate.xsl -o sample.html (siehe Abb. 6.6)

Abb. 6.30: Dieses Beispiel wurde mit der Datei alternate.xsl erzeugt.

msxsl -i sample.xml -s sample.xsl -o sample.html (siehe Abb. 6.7)

Abb. 6.31: Dieses Beispiel wurde mit der Datei sample.xsl erzeugt.

Der gesamte Konvertierungsprozess wird vom XML-Dokument gesteuert. Der XSL-Parser arbeitet dieses Schritt für Schritt durch. Die einzelnen Elemente und ihre Verschachtelungen werden rekursiv durchsucht und mit der Stylesheet-Information verglichen. Existiert für ein Element eine Konstruktionsregel, so wird die im Aktionsabschnitt angegebene Formatierung eingesetzt. Durch den rekursiven Zugriff auf die gesamten Elemente wird die Seite in einzelne handliche Teile zerlegt. Ist man auf der letzten Gliederungsebene angekommen, kann mit den Konstruktionsregeln verglichen werden. Aus einigen einfachen Rules kann so eine sehr komplexe Ausgabestruktur entstehen.

6.1.4 Bezüge innerhalb eines XML-Dokuments

Der XSL-Standard sieht vor, dass auch innerhalb der XML-Datei ein Verweis auf das Stylesheet gegeben werden kann. Das ist wichtig sobald die ersten Browser auf dem Markt sind, die diese Stylesheets verarbeiten können. Solange wir mit einem Parser arbeiten, können wir die Verbindung zwischen XML- und XSL-Dokument per Parameter übergeben.

<?xml:stylesheet href="kunden.xsl" type="text/xsl" ?>

Mit dieser Processing Instruction kann ein Stylesheet fest mit einem XML-Dokument verbunden werden. Als MIME-Typ wird hier der neue Typ "text/xsl" definiert.

Alternativ können auf diese Weise auch die schon bekannten Cascading Stylesheets verwendet werden:

<?xml:stylesheet href="kunden.css" type="text/css" ?>

Hier wird der auch aus HTML schon bekannte MIME-Typ "text/css" verwendet. Für eine Unterstützung der Version 2.0 der CSS-Definition kann auch der MIME-Type "text/css2" benutzt werden.

6.1.5 Bezug innerhalb eines XSL-Stylesheet

Innerhalb eines XSL-Stylesheet lassen sich weitere XSL-Dateien per Verweis integrieren. Somit ist eine Aufteilung größerer Projekte in einzelne Module möglich. Zusätzlich wird die Wiederverwendung von fertigen XSL-Dokumenten erleichtert. Diese müssen nicht per »Copy-Paste« in einer Datei zusammengeführt werden, sondern können über den folgenden Befehl eingeschlossen werden:

<import href="kunden.xsl"/>

6.1.6 Konstruktionsregel (construction rule)

XSL-Anweisungen werden in einem externen Dokument mit der Endung ».xsl« abgelegt. Diese Datei enthält die physischen Übersetzungen zu den dort definierten Befehlen. Eine einzelne Stilanweisung oder auch Konstruktionsregel (engl. construction rule) gliedert sich in zwei zusammenhängende Teile:

Konstruktionsregel:

Durch das Muster wird festgelegt auf welchen (selbstdefinierten) XML-Befehl sich die dann folgende Stilanweisung (Action) bezieht. Das Muster ist das Auswahlkriterium, wann die definierte Ausgabeform auf den Inhalt eines Markups umzusetzen ist.

Wurde das angegebene Muster im XML-Dokument erkannt, dann folgt die Umwandlung des betreffenden Elements in die angegebene Ausgabeform. Eine »action«-Anweisung kann neben passiven Elementen zur reinen Stilgestaltung auch dynamische Anweisungen, beispielsweise den Aufruf eines JavaScripts oder anderer Skriptsprachen enthalten.

Der Inhalt der XSL-Datei wird mit dem Markup <xsl> umschlossen. Der Inhalt besteht aus den dann folgenden Regeln, die mit <rule> markiert werden. So entsteht das Grundgerüst einer XSL-Datei:

<xsl>
  <rule>
    <!-- Konstruktionsregel 1 -->
  </rule>
  <rule>
    <!-- Konstruktionsregel 2 -->
  </rule>
</xsl>

Abb. 6.32: Struktur eines XSL-Dokuments

Eine vollständige XSL-Datei, die unser vorher definiertes Markup <geburtsdatum> mit der Schriftfarbe »Rot« und dem Font-Style »Fett« versieht, finden Sie im Folgenden kurzen Listing:

<xsl>
  <rule>
    <target-element type="geburtsdatum"/>
    <H1 COLOR="red" font-style="bold">
      <children/>
    </H1>
  </rule>
</xsl>

Dieses Beispiel setzt Definitionen analog zum CSS-Standard zur Festlegung der Stileigenschaften ein. Das XSL-Stylesheet dient hier in erster Linie der Umwandlung einer XML-Datei in ein HTML-Dokument unter Zuhilfenahme der Stilinformationen. Im Bereich der Konvertierung von XML zu HTML als Ausgabeformat wird in nächster Zukunft die Hauptaufgabe des XSL-Standards liegen.

Wichtig in unserem Beispiel ist, dass die Stilinformationen mit einem HTML-Element transportiert werden müssen (in unserem Fall ist es das Markup <H1>). An dieses Element werden die visuellen Informationen weitergegeben. Bei der anschließenden Konvertierung des Dokuments in HTML, gehen die semantischen Informationen verloren und werden durch physische Auszeichnungen ersetzt.

XSL basiert auf der XML-Syntax. Alle Befehle und Tags sind daher »case-sensitive« in Kleinbuchstaben einzugeben.

Bevor wir in die genauere Erklärung der einzelnen Elemente der XSL-Definition einsteigen, noch ein komplexeres Beispiel bestehend aus XML-Dokument, entsprechendem XSL-Stylesheet und der daraus geformten HTML-Datei:

XML-Dokument

<?xml version="1.0"?>
<stammdaten>
  <kunde>
    <kuerzel>        ME100      </kuerzel>
    <region>        Nord 2      </region>
    <umsatz>        2056      </umsatz>
  </kunde>
  <kunde>
    <kuerzel>        AB800      </kuerzel>
    <region>        West 1      </region>
    <umsatz>        500      </umsatz>
  </kunde>
</stammdaten>

XSL-Definition

<xsl>
  <rule>
    <target-element type="kuerzel"/>
    <H1 COLOR="blue">
      <children/>
    </H1>
  </rule>
  <rule>
    <target-element type="region"/>
    <H2 COLOR="red">
      <children/>
    </H2>
  </rule>
  <rule>
    <target-element type="umsatz"/>
    <P COLOR="yellow">
      <children/>
    </P>
  </rule>
</xsl>

Daraus konvertierte HTML-Datei:

<HTML>
<HEAD></HEAD>
<BODY>
  <H1 STYLE="color:blue">                  ME100    </H1>
  <H2 STYLE="color:red">                  Nord 2    </H2>
  <P  STYLE="color:yellow">                  2056    </P>

  <H1 STYLE="color:blue">                  AB800     </H1>
  <H2 STYLE="color:red">                  West 1    </H2>
  <P  STYLE="color:yellow">                  500    </P>
</BODY>
</HTML>

Der Parser erstellt nicht automatisch vollständige HTML-Dokumente inklusive der Grundstruktur. Tags wie <HTML> und <BODY> müssen zusätzlich definiert werden. Sie erfahren unter »Basis-Konstruktionsregel« (root rule) wie das funktioniert!

Abb. 6.33: Das HTML-Dokument im Browser, als Ziel unserer Bemühungen.

6.2 Cascading Stylesheets (CSS)

Der begrenzte Umfang und die Intention dieses Buches erlauben es uns nicht eine vollständige CSS-Referenz zu liefern. Trotzdem möchten wir einen kleinen Einblick in dieses für XSL wichtige Thema geben. Wir vernachlässigen eine Einführung über den Einsatz von CSS unter HTML und konzentrieren uns ganz auf den Einsatz mit XML.

6.2.1 CSS2 Processing Model

Das W3C hat zur CSS Version 2.0 ein theoretisches Modell entwickelt, das beschreibt wie ein Prozessor oder Parser mit der Stylesheet-Information umzugehen hat.

6.2.2 Syntax

In HTML existieren zwei Möglichkeiten die Stildefinitionen im Quelltext unterzubringen. Einerseits können die Angaben direkt im Kopf des Dokuments erfolgen, andererseits ist auch eine Übergabe als Parameter innerhalb des Elements möglich.

<HTML>
  <HEAD>
    <STYLE TYPE="text/css">
      div { color: red }
    </STYLE>
  </HEAD>
  <BODY>
    <DIV>Hier steht der Text in der Farbe ROT</DIV>
  </BODY>
</HTML>

In der HTML-Version 4.0 wurde zusätzlich der Parameter STYLE geschaffen. (Nicht zu verwechseln mit dem oben eingesetzten gleichnamigen Markup, der schon in Version 3.2 existierte.)

<DIV STYLE="color: red">

Die Stildefinition wird so direkt im Element untergebracht.

Sie können die Stylesheets für ein HTML-Dokument auch in einer externen Datei unterbringen. Im HTML-Dokument verweisen Sie in diesem Fall wie folgt auf die externe Definition (innerhalb des HEAD-Abschnitts):

<LINK REL="stylesheets" HREF="style.css" TYPE="text/css">

Die CSS-Datei (style.css) enthält die reinen Stilanweisungen in folgender Form:

h1    { color: red }
h2     { color: blue }
h3     { color: black }
h4     { font-size: 12pt }
h5    { font-size: 10pt }
h6    [ font-size: 8pt }

Wir haben die CSS-Definitionen hier in erster Linie im Zusammenhang mit XSL gebracht. Diese XSL-Dateien verwenden die CSS-Funktionen zur Auszeichnung. Das eigentliche Stylesheet, das dann zusammen mit der XML-Datei verwendet wird, ist vom Type XSL.

Trotzdem sollte eine weitere Möglichkeit der Stilauszeichnung nicht unerwähnt bleiben: CSS2 lässt sich auch direkt als Stylesheet-Sprache für XML-Dokumente einsetzen.

Allerdings existieren bisher noch keine Programme, die diese beiden Teile zusammenbringen. Die offizielle CSS2-Definition des W3C sieht aber auch einen Einsatz unter XML vor. Die CSS-Stylesheet-Datei wird dann direkt im Dokument referenziert:

<?xml:stylesheet type="text/css" href="style.css"?>
<dokument>
  <titel>Kapitel 6</titel>
  <autor>Gunter Wielage</autor>
  <inhalt>Eine XSL Einführung</inhalt>
</dokument>

Die zugehörige Datei style.css:

titel, autor            { color: red }
dokument, inhalt            { color: blue }

Parallel zur folgenden Definition innerhalb eines HTML-Dokuments, gemäß der HTML 4.0-Definition, lassen sich auch die Parameter title, media und charset einsetzen:

<LINK HREF="style.css"
  TITLE="Buch" REL="stylesheet" TYPE="text/css">

Im XML-Dokument sieht die Referenz auf das CSS-Stylesheet wie folgt aus:

<?xml:stylesheet href="style.css"
  title="Buch" type="text/css"?>

Es existiert eine fast unüberschaubare Fülle an Befehlen (inzwischen über 100), deren Optionen und Parameter, die unter CSS2 zu verwenden sind. Wir beschränken uns bei unserer kleinen Referenz auf die zahlreichen Möglichkeiten zur Modifikation des Schriftbildes.

Beachten Sie, dass im XSL-Quelltext auf eine Angabe des STYLE-Tags verzichtet werden kann. CSS-Elemente können direkt als Attribut innerhalb des Markups übergeben werden.

<DIV font-size="12pt">

Aus der obigen Stildefinition innerhalb einer XSL-Definition, wird nach der Konvertierung in eine HTML-Datei mithilfe des Parsers ein korrektes STYLE-Attribut:

<DIV STYLE="font-size: 12pt">

Wir setzen in den folgenden Beispielen, die XSL-typische Schreibweise ein.

6.2.3 font-family

Mit dieser Referenz kann man die Schriftfamilie näher spezifizieren, die eingesetzt werden soll. Die korrekte Ausführung im Browser hängt stark vom verwendeten System und den installierten Schriften ab.

Parameter: <family-name> | <generic-family>

Beispiel: <DIV font-family="Arial">

family-name Name des Fonts (Bsp. Arial, Symbol, Times, Helvetica)

generic-family Um einen robusteren Code unabhängig von installierten Schriften zu erzeugen, kann man noch die Schriftfamilie näher definieren. Falls die angegebene Schrift auf dem Rechner nicht existiert, wird dann eine ähnliche Schrift verwendet. Mögliche Angaben sind: »serif", "sans-serif", "cursive", "fantasy", "monospace".

6.2.4 font-size

Der wichtigste Faktor ist sicherlich die Größe der Schrift, diese lässt sich prozentual und absolut verändern.

Parameter: <length> | <percentage>

Beispiel: <DIV font-size="12pt">

length Definiert die absolute Größe der Schrift in der Maßeinheit Punkte. Diese Einstellung ist unabhängig vom verwendeten System und von voreingestellten Schriftgrößen (Bsp.: »12pt").

percentage Erlaubt eine relative Änderung der Schriftgröße zur voreingestellten Standardschrift (Bsp.: »150%" ).

6.2.5 font-weight

Dieser Parameter gibt Auskunft über die Schriftstärke, von normal starker bis zu fetter Schrift.

Parameter: <weight>

Beispiel: <DIV font-weight="bold">

normal Normale Schriftstärke (entspricht einem Zahlenwert von »400").

bold Fettschrift (entspricht einem Zahlenwert von »700").

bolder Bewirkt eine automatische Steigerung der Schriftstärke gegenüber der verwendeten Standardschrift um eine Stufe.

lighter Bewirkt eine Verringerung der Schriftstärke um eine Stufe.

Zusätzlich kann die Schriftstärke auch als Zahlenwert von »100" bis »900" angegeben werden.

6.2.6 font-style

Über den font-style kann man zwischen normaler und kursiver Ausrichtung der Schrift auswählen.

Parameter: <style>

Beispiel: <DIV font-style="italic">

normal Der Standardwert ist die normale Schrift.

italic Mit diesem Wert erzeugen Sie ein kursives Schriftbild.

6.2.7 font-stretch

Die Schriftweite lässt sich über die Referenz font-stretch beeinflussen.

Parameter: <stretch>

Beispiel: <DIV font-stretch="condensed">

Als Parameter lassen sich die folgenden Schlüsselwörter übergeben. Sie sind in aufsteigender Reihenfolge von sehr gedrungener bis zu sehr weiter Schrift aufgelistet:

ultra-condensed
extra-condensed
condensed
semi-condensed
normal
semi-expanded
expanded
extra-expanded
ultra-expanded

6.2.8 color

Bringen Sie ein bisschen Farbe ins Spiel. Mit color ändern Sie die Farbe des Elements, in der Regel die des eingeschlossenen Textes.

Parameter: <color>

Beispiel: <DIV color="red">

color Die Farbe kann entweder als Schlüsselwort übergeben werden (Bsp.: »red«) oder als zusammengesetzter RGB-Wert (Bsp.: »rgb(0,0,255)"). Der RGB-Wert gibt die einzelnen Farbanteile der Farben Rot, Gelb und Blau an und stellt daraus eine zusammengesetzte Farbe her. Gültige Werte für die drei Anteile sind Zahlen zwischen 0 und 255.

6.2.9 background-color

Die Hintergrundfarbe eines Elements geben Sie über die background-color an.

Parameter: <color>

Beispiel: <DIV background-color="red">

color Die Farbe kann entweder als Schlüsselwort übergeben werden (Bsp.: »red«) oder als zusammengesetzter RGB-Wert (Bsp.: »rgb(0,0,255)").

6.2.10 display

Um dem Browser mitzuteilen, ob auf ein Textelement ein automatischer Zeilenumbruch erfolgt, wird das Schlüsselwort display verwendet. Innerhalb eines Textes erfolgte Zuweisungen erfordern gewöhnlich keinen Zeilenumbruch, während Elemente wie Absätze natürlich mit einem Zeilenumbruch abschließen.

Parameter: <display>

Beispiel: <DIV display="inline">

display Elemente, die sich innerhalb eines Textes befinden (beispielsweise als Zitat gekennzeichnete Sätze) sollen meist nicht umgebrochen werden, hier ist der Parameter inline zu verwenden. Andere Elemente auf die zwingend ein Zeilenumbruch erfolgt (beispielsweise der Titel) werden als block gekennzeichnet.

6.2.11 margin

margin gibt den Abstand zum nächsten Absatz an.

Parameter: <size>

Beispiel: <DIV margin="10pt">

size Der Abstand wir in der Maßeinheit Punkte angegeben (Bsp.: »10pt").

6.2.12 word-spacing

Gibt den Abstand zwischen den einzelnen Wörtern an.

Parameter: <size>

Beispiel: <DIV word-spacing="10">

size Die Länge des Abstands zwischen den Wörtern kann als absolute Zahl oder als Schlüsselwort "normal" für die Voreinstellung angegeben werden.

6.2.13 letter-spacing

Ähnlich wie die Funktion word-spacing gibt letter-spacing nicht den Abstand zwischen ganzen Wörtern, sondern den Abstand zwischen einzelnen Buchstaben wieder.

Parameter: <size>

Beispiel: <DIV letter-spacing="10">

size: Die Länge des Abstands zwischen den einzelnen Buchstaben kann als absolute Zahl oder als Schlüsselwort "normal" für die Voreinstellung angegeben werden.

6.2.14 text-decoration

Optionale Attribute zur »Dekoration« des Textes wie unterstrichen oder blinkend werden über den Parameter text-decoration festgelegt.

Parameter: <decoration>

Beispiel: <DIV text-decoration="underline">

decoration: Die folgenden Schlüsselwörter lassen verschiedene Text-Dekorationen zu:

none keine besondere Textdekoration (Standardeinstellung)

underline unterstrichen

overline Linie über dem Text

line-through durchgestrichen

blink blinkend

6.2.15 text-transform

text-transform führt eine Umwandlung der Buchstabengröße beispielsweise in Großbuchstaben oder Kleinbuchstaben durch (siehe Abb. 6.10).

Abb. 6.34: Alle Attribute von »text-transform« im Einsatz.

Parameter: <transform>

Beispiel: <DIV text-transform="lowercase">

transform: Die folgenden Schlüsselwörter können zur Umwandlung der Buchstabengröße eingesetzt werden:

none keine Veränderungen (Standardeinstellung)

capitalize Der erste Buchstabe jedes Wortes wird als Großbuchstabe dargestellt.

uppercase Alle Buchstaben werden in Großbuchstaben umgewandelt.

lowercase Alle Buchstaben werden in Kleinbuchstaben umgewandelt.

6.2.16 text-align

Jeder Text lässt sich mit diesem Parameter vertikal ausrichten.

Parameter: <align>

Beispiel: <DIV text-align="center">

align: Die Ausrichtung erfolgt nach den in HTML bekannten Schlüsselwörtern.

left Ausrichtung linksbündig

right Ausrichtung rechtsbündig

center Ausrichtung zentriert

Die kompletten und äußerst umfangreichen Definitionen zur Version 2.0 der Cascading Style Sheets finden Sie im Internet (siehe Abb. 6.11).

Abb. 6.35: http: //www.w3c.org/TR/REC-CSS2/

6.3 Konstruktionsregeln (rules)

Mithilfe der Konstruktionsregel wird dem mit dem Muster übereinstimmenden semantischen Tag eine Formatierung zugewiesen. Eine Konstruktionsregel (»construction rule«) besteht aus den beiden Elementen Muster und Aktion. Innerhalb des Musters wird über einen Suchtext der Markup-Befehl definiert. Dieser Markup-Befehl erhält dann durch den Konvertierungsprozess die im »action«-Bereich angegebene Formatierung.

Innerhalb eines XSL-Dokuments können beliebig viele »rule«-Abschnitte festgelegt werden. Eine Konstruktionsregel wird durch den Befehl <rule> eingeleitet und durch das abschließende </rule>-Tag geschlossen.

<xsl>
  <rule>
    <target-element/>
    <p>
      <children/>
    </p>
  </rule>
</xsl>

Über das leere Markup <children/> wird dem Parser mitgeteilt an welcher Stelle genau der Inhalt des Zielelements eingesetzt werden soll.

Existieren für ein Element mehrere Konstruktionsregeln mit übereinstimmendem Muster, so wird die Regel vorgezogen, die das Element am genauesten spezifiziert. In den meisten Fällen wird dies die Konstruktionsregel sein, die größere Anzahl an beschreibenden Attributen enthält.

<rule>
  <target-element type="nachname"/>
  <B>
    <children/>
  </B>
</rule>

Die nächste Konstruktionsregel wird der Parser der vorangegangenen Definition vorziehen:

<rule>
  <element type="adresse">
    <target-element type="nachname"/>
  </element>
  <P>
    <children/>
  </P>
</rule>

Existieren mehrere völlig identische Muster, so wählt der Parser üblicherweise die Regel aus, die sich weiter am Ende des Quelltextes befindet.

6.3.1 Basis-Konstruktionsregel (root rule)

Mit der Basis-Konstruktionsregel wird die Grundstruktur des Dokuments, in diesem Fall die eines HTML-Dokuments, festgelegt. Bevor der Parser das Dokument zusammenstellt, sucht er diese durch das Schlüsselwort root rule gekennzeichnete Konstruktionsregel heraus und fügt dann alle weiteren Elemente in diese Struktur ein.

<rule>
  <root/>
  <HTML>
    <HEAD>
      <TITLE>Titel des Dokuments</TITLE>
    </HEAD>
    <BODY>
      <children/>
    </BODY>
  </HTML>
</rule>

Eine Root Rule kann natürlich noch wesentlich ausführlicher und länger sein, als das hier dargestellte Beispiel. Sie könnten beispielsweise zusätzlich META-Tags oder JavaScripte einfügen.

6.4 Flow Objects

Das Ergebnis einer über die Konstruktionsregel zugewiesenen Formatierung ist immer ein bestimmtes typografisches Objekt. Hierbei kann es sich beispielsweise um eine Überschrift oder einen Absatz handeln. Für solche Objekte existiert eine einheitliche Bezeichnung: das Flow Object. Dabei spielt es keine Rolle, ob das Flow Object in Anlehnung an den CSS-Standard oder DSSSL erzeugt wird. Insbesondere bei DSSSL, das mit einer wesentlich höheren Anzahl an Objekten ausgestattet ist, können Flow Objects nicht nur, wie in CSS, statische Formatierungselemente sein, sondern vielmehr dynamische Elemente.

Alle Flow Objects einer Seite bilden eine hierarchische Struktur. Die Baumstruktur mit ihren einzelnen Verschachtelungen wird Flow Object Tree genannt. Das Wurzelelement eines Dokuments ist die Seite selbst. Weitere Flow Objects der Seite sind beispielsweise Absätze, Tabellen und in der letzten Baumebene die eingeschlossenen Textpassagen selbst. Der Text »fließt« in die einzelnen Elemente und so ist auch die englische Bezeichnung zu verstehen.

Eine grobe Unterteilung der Flow Objects erfolgt in fünf Gruppen:

Beispiel: Eine Überschrift oder der Titel der Seite.

Beispiel: Eine Telefonnummer in einer Adressentabelle.

Beispiel: Ein in HTML als Zitat gekennzeichneter Text.

Beispiel: Eine Sprungadresse auf eine andere Internet-Präsenz.

Beispiel: Grafiken, Videos, Sound (siehe Abb. 6.12).

Eine einzelne Konstruktionsregel kann eine Vielzahl verschiedener Flow Objects enthalten. Das folgende Beispiel enthält insgesamt vier Flow Objects: <DIV>, <BR>, <HR> und <B>. Das letzte Flow Object enthält zusätzlich noch einen Text als Inhalt (content).

<xsl>
  <rule>
    <target-lement type="vorname"/>
    <DIV>
      <BR/>
      <HR/>
      <children/>
      <B>Ende des Textes</B>
    </DIV>
  </rule>
</xsl>

Abb. 6.36: Darstellung einiger ausgewählter Flow Objects einer HTML-Seite.

Der von Microsoft vorgelegte XSL-Parser unterstützt bisher noch nicht alle Flow Object Typen! Beispielsweise sind Flow Object Makros oder erweiterte Flow Object Typen noch nicht in die aktuelle Version integriert.

In der aktuellen XSL-Version werden Flow Objects aus HTML und CSS eingesetzt. In Zukunft werden auch DSSSL-Elemente Einzug finden. Folgende Flow Objects können Sie zur Zeit einsetzen (Quelle: Microsoft).

6.4.1 HTML-Befehle

Da XML case-sensitive ist, müssen alle HTML-Befehle in Großbuchstaben angegeben werden, um Konflikte zu vermeiden.

AREA,
BASE, BASEFONT, BGSOUND, BR,
COL, COLGROUP,
FRAME,
HR,
IMG, INPUT, ISINDEX,
LINK,
META,
PARAM,
WBR
DD, DT, LI, OPTION, P, TD, TH, THEAD, TR
AREA   (NOHREF, NOTAB),   DIR   (COMPACT),
DIV   (NOWRAP),   DL   (COMPACT),
FRAME   (NORESIZE),   HR   (NOSHADE),
IMG   (CONTROLS),   INPUT  (CHECKED, NOTAB),
OL   (COMPACT),   OPTION  (SELECTED),
TABLE   (NOWRAP),   TD   (NOWRAP),
TH   (NOWRAP),   TR   (NOWRAP),
UL   (COMPACT),   MENU   (COMPACT),
OBJECT   (DECLARE, NOTAB, SHAPES),

6.4.2 CSS Befehle

font-family,  font-style,  font-variant,
font-weight,  font-size,  font,
letter-spacing,  line-height,  text-decoration,
text-transform,  text-align,  text-indent,
vertical-align,  color,  background-color,
background-image,  background-repeat,
background-attachment,  background-position,
background,  margin-top,  margin-right,
margin-bottom,  margin-left,  margin,
padding-top,  padding-right,  padding-bottom,
padding-left,  padding,  border-top-width,
border-right-width,  border-bottom-width,
border-left-width,  border-width,  border-top-color,
border-right-color,  border-bottom-color,
border-left-color,  border-color,  border-top-style,  
border-right-style,  border-bottom-style,
border-left-style,  border-style,  border-top,
border-right,  border-bottom,  border-left,
border,  float,  clear,
display,  list-style-type,  list-style-image,
list-style-position,  list-style,  clip,
height,  left,  overflow,
position,  top,  visibility,
width,  z-index,  page-break-before,
page-break-after,  filter,  word-spacing,
white-space

6.5 Muster (pattern)

Mithilfe des definierten Musters versucht der Parser im Abgleich mit der XML-Datei passende Übereinstimmungen zu finden. Das Muster ist nichts anderes als ein Suchtext, der zur Identifizierung des Elements dient, auf das die Konstruktionsregel angewendet werden soll.

6.5.1 Target-Element

Jede Konstruktionsregel muss mindestens ein solches Muster oder target-element (Zielelement) enthalten. Eine Ausnahme bildet die unter Wildcards beschriebene Vorgehensweise. Das folgende Muster sucht im XML-Dokument alle Elemente, die mit dem Tag "vorname" versehen sind:

<target-element type="vorname"/>

6.5.2 Mehrfache Muster (multiple patterns)

Neben der Angabe nur eines Musters ist es auch möglich gleich mehrere Zielelemente festzulegen und diese so mit einer einzigen Konstruktionsregel mit einer einheitlichen Formatierung zu versehen.

<xsl>
  <rule>
    <target-element type="vorname"/>
    <target-element type="nachname"/>
    <target-element type="plz"/>
    <target-element type="ort"/>
    <P font-weight="bold">
      <children/>
    </P>
  </rule>
</xsl>

Alle angegebenen Elemente "vorname", "nachname", "plz" und "ort" werden im Beispiel durch die Formatierung "bold" (Fettschrift) ergänzt.

6.5.3 Element

Die einfachste Definition eines Musters berücksichtigt den Kontext in dem sich der Markup-Befehl befindet nicht. Oft ist diese Berücksichtigung nicht notwendig, in komplexeren Dokumenten findet aber häufig auch eine zusätzlich Angabe zum Kontext Verwendung. Wie im folgenden Beispiel, eine Adressenliste, die zwischen privaten und geschäftlichen Adressen unterscheidet. Die Angabe eines zusätzlichen Kontextes erfolgt über das Tag <element>. Über das Attribut type wird ein weiteres Muster angegeben innerhalb dessen sich das Target-Element befinden muss.

<?xml version="1.0"?>
<private>
  <adresse>
      <vorname>        Wolfgang      </vorname>
      <nachname>        Meier      </nachname>
  </adresse>
</private>
<geschaeftlich>
  <adresse>
      <vorname>        Jürgen      </vorname>
      <nachname>        Müller      </nachname>
  </adresse>
</geschaeftlich>

Hier sollen nicht nur die Vornamen und Nachnamen unterschiedlich dargestellt werden, sondern es soll eine zusätzliche visuelle Unterscheidung zwischen den privaten und geschäftlichen Kontakten möglich sein.

<xsl>
<rule>
  <!-- Muster für private Adressen / Vorname -->
  <element type="private">
    <target-element type="vorname">
  </element>
  <P color="red">
    <children/>
  </P>
</rule>

<rule>
  <!-- Muster für private Adressen / Nachname -->
  <element type="private">
    <target-element type="nachname">
  </element>
  <P color="red" font-style="bold">
    <children/>
  </P>
</rule>

<rule>
  <!-- Muster für geschäftliche Adressen / Vorname -->
  <element type="geschaeftlich">
    <target-element type="vorname">
  </element>
  <P color="blue">
    <children/>
  </P>
</rule>

<rule>
  <!-- Muster für geschäftliche Adressen / Nachname -->
  <element type="geschaeftlich">
    <target-element type="vorname">
  </element>
  <P color="blue" font-style="bold">
    <children/>
  </P>
</rule>

</xsl>

Die Angabe weiterer Elemente beschränkt sich nicht nur auf ein einziges übergeordnetes Element. Es kann eine weitere Verschachtelung von Elementen in mehreren Stufen erfolgen:

<element type="artikel">
  <element type="preise">
    <element type="einkaufspreis">
      <target-element type="netto"/>
    </element>
  </element>
</element>

XSL akzeptiert ausschließlich einfache »Eltern-Kind-Beziehungen« bzw. »Vater-Kind-Beziehungen« (parent relationship). Weitere aus der Informatik bekannten Beziehungsmodelle für Datenbanken (Bsp. »Geschwisterbeziehungen«) werden nicht oder noch nicht unterstützt.

6.5.4 Wildcards

Ein Muster enthält eine Zeichenkette, die mit dem Markup-Befehl übereinstimmen muss, dessen Formatierung in der Konstruktionsregel definiert wird. Um eine einzige Konstruktionsregel für mehrere Elemente zu definieren, haben wir schon die Lösung kennengelernt mehrere Zielelemente anzugeben. Mithilfe von so genannten Wildcards (Joker), Muster die mit allen angegebenen Elementen übereinstimmen, lässt sich diese Möglichkeit noch ausbauen.

Ein Muster, das Wildcards enthält, wird durch den Befehl <target-element/> (ohne weiteren Inhalt) festgelegt.

<rule>
  <target-element/>
  <P font-style="bold">
    <children/>
  </P>
</rule>

Mithilfe des <element>-Tags kann zusätzlich das übergeordnete Element festgelegt werden.

<rule>
  <element type="artikel">
    <target-element/>
  </element>
  <DIV font-style="bold">
    <children/>
  </DIV>
</rule>

Das obige Beispiel setzt alle direkten Nachkommen des Elements <artikel> in Fettschrift ein. Beim Einsatz dieser Art von Wildcards ist zu beachten, dass immer nur die direkten Nachkommen eines Elternelements von der Definition betroffen sind. Weitere Nachkommen der nächsten Generation werden nicht berührt (siehe Abb. 6.13).

Abb. 6.37: Lediglich unmittelbare Nachkommen (children) des Elements sind in die Änderungen eingeschlossen.

Es existiert allerdings auch eine weitere Lösung, um auch die nächste Abstammungs-Generation eines Elements mit in Formatierung einzubeziehen.

6.5.5 Any-Element

Um alle Nachkommen mithilfe einer Wildcard-Definition des Zielelements zu berücksichtigen, kann der Befehl <any> eingesetzt werden.

Vergleichen Sie die folgende Skizze mit der vorangegangenen Übersicht. Der Unterschied der betroffenen Elemente wird so schnell ersichtlich.

Abb. 6.38: Mithilfe des <any>-Attributs lässt sich die Menge auf die gesamte Nachkommenschaft des Ursprungslements vergrößern.

Im folgenden Beispiel wird jedes nachfolgende Element des Elternelements »artikel« mit der Formatierung »Fettschrift« versehen:

<xsl>
<rule>
  <element type="artikel">
    <any>
      <target-element/>
    </any>
  </element>
  <P font-style="bold">
    <children/>
  </P>
</rule>

Das <any>-Tag findet nicht nur in Verbindung mit einem leeren target-element Verwendung. Im Zielelement kann zusätzlich auch noch ein spezieller Typ angegeben werden.

<xsl>
<rule>
  <element type="artikel">
    <any>
      <target-element type="beschreibung"/>
    </any>
  </element>
  <P>
    <children/>
  </P>
</rule>

So sind alle Elemente betroffen, die dem beschriebenen Muster folgen. Inklusive des Zielelements selbst.

6.5.6 Attribute

Es lässt sich nicht nur der Name des Elements selbst im Muster angeben, sondern auch ein im Element verwendetes Attribut.

<bezeichnung gruppe="software">
  Microsoft XML-Notepad
</bezeichnung>

Möchte man auf das Attribut gruppe="software" zugreifen, so müssen mithilfe des Befehls <ATTRIBUTE> die zwei Werte name und value übergeben werden.

name bezeichnet den Namen des im Markup verwendeten Attributs

value bezeichnet den Wert des eingesetzten Attributs

Das folgende Beispiel macht diesen Zusammenhang und die Verwendung des Befehls deutlich. Zu beachten ist, dass <attribute> innerhalb des Zielelements angegeben wird. Das target-element ist hier also im Gegensatz zum sonstigen Einsatz kein leeres Element!

<?xml version="1.0"?>
<liste>
  <bezeichnung gruppe="software">
    Microsoft XML-Notepad</bezeichnung>
    <artikel>msxml</artikel>
  </bezeichnung>

  <bezeichnung gruppe="hardware">
    Farbbildschirm 17"
    <artikel>fb17</artikel>
  </bezeichnung>
</liste>

Das XML-Dokument enthält zwei Artikel, die jeweils über ein Attribut näher spezifiziert sind. Möchte man nun allen Artikeln, die den Gruppen Software und Hardware zugeordnet sind, unterschiedliche Formatierungen zuweisen, so kann man hierzu das Markup <attribut> einsetzen.

Um die zwei unterschiedlichen Verwendungen des Elements "bezeichnung" zu differenzieren, ist jeweils der Wert des Attributs "gruppe" näher angegeben:

<target-element type="bezeichnung">
  <attribut name="gruppe" value="software"/>
</target-element>

<target-element type="bezeichnung">
  <attribut name="gruppe" value="hardware"/>
</target-element>

Um einen weiteren Nachfolger des Elements "bezeichnung" zu definieren, lässt sich <attribute> auch im Zusammenhang mit <element> verwenden:

<element type="bezeichnung">
  <attribute name="gruppe" value="software"/>
  <target-element type="artikel"/>
</element>

Häufig wird es notwendig sein zu überprüfen, ob überhaupt ein Wert für ein Attribut eingesetzt wurde. Das oben eingeführte Markup <bezeichnung> hätte ja auch ohne Angabe einer "gruppe" genutzt werden können. In diesem Fall führt unsere Überprüfung des Inhalts dieses Attributs leider nicht weiter.

<bezeichnung>
  XML - Praxis und Referenz
</bezeichnung>

Statt "value" wird einfach das Schlüssewort "has-value" eingesetzt. Gültige Werte zur Überprüfung des Inhalts sind "yes" (= ein Wert ist vorhanden) und "no" (= kein Wert vorhanden).

Um zu überprüfen, ob eine Gruppe angegeben wurde, sind die folgenden beiden Syntaxbeispiele möglich:

<target-element type="bezeichnung">
  <!-- kein Wert für "gruppe" vorhanden -->
  <attribute name="gruppe" has-value="no">
</target-element>

<target-element type="bezeichnung">
  <!-- es existiert ein Wert für "gruppe" -->
  <attribute name="gruppe" has-value="yes">
</target-element>

Welchen Wert "gruppe" hat, spielt im zweiten Beispiel keine Rolle. Es wird lediglich zwischen leerem oder nicht vorhandenem Attribut und dem Vorhandensein eines Attributs unterschieden.

6.5.7 Qualifiers

Manchmal ist es vorteilhaft, wenn man bestimmte Elemente einer Gruppe herausgreifen kann, um diesen eine bestimmte Formatierung zuzuweisen. Beispielsweise könnte man in einer Adressenliste vor dem ersten Element der Liste und hinter dem letzten Element der Liste eine horizontale Linie einfügen.

<?xml version="1.0"?>
<liste>
  <adresse>     <!-- erstes Element -->
    <nachname>        Müller      </nachname>
    <vorname>        Thorsten      </vorname>
  </adresse>
  <adresse>
    <nachname>        Meier      </nachname>
    <vorname>        Wilhelm      </vorname>
  </adresse>
  <adresse>      <!-- letztes Element -->
    <nachname>        Schulz      </nachname>
    <vorname>        Rita      </vorname>
  </adresse>
</liste>

Abb. 6.39: Vor dem ersten Eintrag und hinter dem letzten Eintrag der Liste soll eine besondere Formatierung (horizontale Linie) eingefügt werden.

In XSL existiert hierzu das Attribut "position", das dem target-element zugefügt wird. Über position lässt sich so festlegen, dass beispielsweise das erste Element einer Gruppe von der Formatierung betroffen ist.

<rule>    
  <target-element type="adresse" position="first-of-type"/>
  <P>
    <children/>
  </P>
</rule>

Als Wert für das Attribut position sind die folgenden vier Schlüsselwörter definiert:

Schlüsselwort Bedeutung
first-of-type
Erster Nachkomme eines Elements dieses Typs.
last-of-type
Letzter Nachkomme eines Elements dieses Typs.
first-of-any
Erster Nachkomme eines Elements beliebigen Typs.
last-of-any
Letzter Nachkomme eines Elements beliebigen Typs.

Für unser oben gezeigtes Beispiel ergibt sich die folgende XSL-Definition. Auf eine genauere Formatierung der Vor- und Nachnamen wurde aus Gründen der Übersichtlichkeit verzichtet:

<xsl>

  <!-- erstes Element der Liste -->
  <rule>
    <target-element type="adresse" position="first-of-type"/>
    <DIV>
      <HR/>
      <children/>
    </DIV>
  </rule>

  <!-- letztes Element der Liste -->
  <rule>
    <target-element type="adresse" position="first-of-type"/>
    <DIV>
      <children/>
      <HR/>
    </DIV>
  </rule>

  <!-- alle anderen Elemente der Liste -->
  <rule>
    <target-element type="adresse"/>
      <DIV>
        <children/>
      </DIV>
  </rule>
</xsl>

Bei Verwendung der beiden Werte first-of-any und last-of-any wird das Element nicht näher festgelegt. Beispielsweise könnte grundsätzlich das erste Element einer Auflistung mit dem Muster übereinstimmen und besonders behandelt werden. Dabei spielt es keine Rolle, ob dieses Element vom Typ »adresse« ist.

<rule>
  <element type="liste">
    <target-element position="first-of-any">
  </element>
  <DIV>
    <children/>
  </DIV>
</rule>

Sollte unsere Liste aus dem obigen Beispiel lediglich einen einzigen Eintrag enthalten, so stellt sich das Problem, dass das erste zugleich das letzte Element darstellt.

<?xml version="1.0"?>
<liste>
  <adresse>     <!-- einziges Element -->
    <nachname>        Müller      </nachname>
    <vorname>        Thorsten      </vorname>
  </adresse>
</liste>

Für diesen Ausnahmefall existiert das Attribut only für das target-element. Über dieses Attribut lässt sich eine spezielle Formatierung für das einzige Element einer Liste definieren. Auf unser Beispiel übertragen, heißt das, der einzige Eintrag der Liste sollte mit einer horizontalen Linie über und unter dem Element versehen werden.

Für nur einen Nachkommen des definierten Elements sieht der Befehl dann folgendermaßen aus:

<target-element type="liste" only="of-type">

Neben of-type ist auch der Wert of-any für nicht näher spezifizierte Elemente möglich.

Schlüsselwort Bedeutung
of-type
es existiert nur ein Nachkomme des definierten Typs
of-any
es existiert nur ein Nachkomme eines beliebiges Typs

6.5.8 Style-Rule

Neben der üblichen Konstruktionsregel, die mit <rule> eingeleitet wird existiert ein weiteres Element mit ähnlicher Funktionsweise. Mit dem Markup <style-rule> werden die so genannten Stilregeln festgelegt. Diese übertragen Cascading Style Sheets auf einzelne Elemente. Zur Ausgabe dieser Elemente ist zusätzlich aber noch eine Konstruktionsregel notwendig. Stylerules enthalten keine Angabe eines <children>-Elements, sondern ausschließlich die Anweisung <apply> mit deren Hilfe die Stilanweisungen auf das Element übertragen werden.

<style-rule>
  <target-element/>
  <apply font-style="bold"/>
</style-rule>

Dem folgenden XML-Beispiel werden wir die Schriftgröße 12pt zuweisen.

<?xml version="1.0"?>
<adresse>
  <nachname>        Meier    </nachname>
</adresse>

Zunächst wenden wir die uns schon bekannten Anweisungen der Konstruktionsregel an, um dem einzelnen Element "nachname" die Schriftgröße ("font-size") 12pt zu übergeben.

<rule>
  <target-element type="nachname"/>
  <DIV font-size="12pt">
    <children/>
  </DIV>
</rule>

Das gleiche Ergebnis erzielen wir auch mithilfe einer voranstehenden Stilregel:

<style-rule>
  <target-element type="adresse"/>
  <apply font-size="12pt"/>
</style-rule>

Diese Stilregel weist dem Element allerdings lediglich die Schriftgröße zu und kümmert sich noch nicht um die Ausgabe der Daten. Dazu muss zusätzlich eine Konstruktionsregel festgelegt werden:

<rule>
  <target-element type="adresse"/>
  <DIV>
    <children/>    
  </DIV>
</rule>

Wie man sieht, bringt uns die Verwendung der Stilanweisung nur zusätzlichen Quellcode und noch keine Arbeitserleichterung. Der Vorteil liegt vor allem darin, dass bei der erneuten Ausgabe durch eine Konstruktionsregel, die Stilanweisungen nicht noch einmal anzugeben sind. Die Stilvorgaben sind fest mit dem Element verbunden. Unabhängig davon, ob die Daten einmal in einer Tabelle und das andere Mal in einem Absatz ausgegeben werden. Die Stilvorgaben bleiben erhalten. Hier ist auch die Begründung zu sehen, warum neben den Konstruktionsregeln ein weiteres Element geschaffen wurde.

Denn in den Konstruktionsregeln wird unweigerlich definiert, in welcher Form die Daten ausgegeben werden. Um diesen Schwierigkeiten aus dem Weg zu gehen und von der Art der Ausgabe unabhängig zu werden, wurden zusätzlich die Stilregeln eingeführt. So kann einem Element ein übergreifender Stil mitgegeben werden, auf den bei jeder beliebigen Ausgabe zurückgegriffen wird.

Die Arbeit mit den Stilregeln folgt fast den gleichen syntaktischen Regeln wie die Cascading Style Sheets. So kann auch die in HTML häufig anzutreffende Definition der Klasse eines Elements verarbeitet werden:

<nachname class="neu">Müller</nachname>
<nachname class="alt">Meier</nachname>
<nachname class="alt">Schulze</nachname>

Um in der Stildefinition auf diese Klassen zuzugreifen, verwenden wir den Befehl attribute:

<style-rule>
  <target-element type="nachname">
    <attribute name="class" value="neu"/>
  </target-element>
  <apply color="red"/>
</style-rule>
<style-rule>
  <target-element type="nachname">
    <attribute name="class" value="alt"/>
  </target-element>
  <apply color="black"/>
</style-rule>

Wir weisen so allen als »neu« gekennzeichneten Einträgen die Textfarbe Rot zu und allen alten« Einträgen die Farbe Schwarz. Sollten wir die Adressen anschließend mit einer Konstruktionsregel für die Ausgabe vorbereiten, so sind diese Textfarben schon vorgegeben.

Um bei unserem Beispiel zu bleiben, wäre eine Anwendung denkbar, die grundsätzlich alle neuen Einträge der Liste in Rot hervorhebt. Auf die Angabe eines Elements kann also verzichtet werden, da diese Stilanweisung für sämtliche neuen Daten gelten soll.

<style-rule>
<target-element/>
    <attribute name="class" value="neu"/>
</target-element>
<apply color="red">
</style-rule>

6.6 Aktionen (action)

Wenn das definierte Muster auf ein Element innerhalb eines XML-Dokuments zutrifft, tritt der zweite Teil der Konstruktionsregel in Kraft: die »action«-Anweisung. Diese enthält die Formatierungshinweise, die sich in der sich aus der Konvertierung ergebenden HTML-Datei wiederfinden.

Eingebettet in die Formatierungsbefehle findet sich das <children/>-Tag. Es gibt an, an welcher Stelle innerhalb der physischen Angaben der Inhalt des mit dem Muster übereinstimmenden Elements eingesetzt wird.

<rule>
  <target-element/>
  <P>
    <children/>
  </P>
</rule>

Im folgenden Beispiel wenden wir die oben angegebene Konstruktionsregel auf ein XML-Dokument an. Dabei haben wir explizit kein Muster für das Target-Element angegeben. Auf diese Weise wird die Aktion auf alle enthaltenen Elemente angewendet. Die rekursive Behandlung des Dokuments kommt so voll zum Einsatz.

<privat>
<adresse>
    <vorname>        Hans         </vorname>
    <nachname>        Müller         </nachname>
    <plz>        33100        </plz>
    <ort>        Paderborn        </ort>
  </adresse>
</privat>

Der Parser setzt jetzt beim <privat>-Element an und setzt an die Stelle des Start- und Schluss-Tags ein <p>. Dann verfolgt er rekursiv alle weiteren Elemente des Dokuments. Als Ergebnis erhalten wir die unten angegebene HTML-Datei:

<P>                      <!-- <privat> -->
  <P>                    <!-- <adresse> -->
    <P>Hans          </P>        <!-- <vorname></vorname> -->
    <P>Müller          </P>        <!-- <nachname></nachname> -->
    <P>33100          </P>        <!-- <plz></plz> -->
    <P>Paderborn          </P>        <!-- <ort></ort> -->
  </P>                    <!-- </adresse> -->
</P>                      <!-- </privat> -->

Das Beispiel macht deutlich, dass obwohl die Zusammenführung von XML- und XSL-Dokument für den Parser mit einigem Aufwand verbunden ist, wir es bei der Erstellung der XSL-Definition vergleichsweise leicht hatten. Mit wenigen Zeilen haben wir so ein gesamtes Dokument mit Formatierungshinweisen versehen.

6.6.1 Versteckte Elemente

Es gibt sicherlich viele Gründe, um einzelne Daten einer XML-Datei nicht bei jeder gewünschten Umwandlung in ein HTML-Dokument mit auszugeben. Vielleicht möchten Sie bei einer Adressenliste, die neben geschäftlichen Daten auch private Hinweise enthält, einzelne Elemente von der Veröffentlichung ausklammern. XSL bietet dazu eine einfache und wirkungsvolle Möglichkeit. Lassen Sie einfach den Befehl <children/>, der sonst angibt an welcher Stelle der Inhalt des Elements eingesetzt wird, wegfallen.

<rule>
  <target-element type="privat"/>
</rule>

Natürlich können Sie statt dessen auch einen Hinweis ausgeben lassen:

<rule>
  <target-element type="privat"/>
  <B>-- Private Daten gelöscht! --</B>
  <BR/>
</rule>

6.6.2 Filtern

Eine der herausragenden Fähigkeiten von XSL ist es, Inhalte eines XML-Dokuments umzustrukturieren und Teilbereiche herauszufiltern. Eine Adressenliste könnte so beispielsweise einmal nach Vornamen und dann nach Nachnamen sortiert ausgegeben werden. Das Tag <select-elements>, das sich innerhalb der Aktion befindet und das <children/>-Element ersetzt, ergänzt XSL um diese Funktion zum Filtern von bestimmten Elementen.

<select-elements>
  <target-element type="nachname"/>
</select-elements>

Das <select-elements>-Tag enthält zwar auch ein Suchmuster, das über das <target-element> bestimmt wird. Dieses Suchmuster hat aber keine Bedeutung für das Muster der Konstruktionsregel.

Folgendes Beispiel sucht die unmittelbaren Nachkommen nachname des Elements adresse.

<xsl>
<rule>
  <target-element type="adresse"/>
  <DIV>
    <select-elements>
    <target-element type="nachname"/>
    <select-element>
  </DIV>
</rule>
</xsl>

Sollen Elemente aus dem Dokument herausgefiltert werden, die keine unmittelbaren Nachkommen des Musters der Konstruktionsregel sind, wird das Attribut from verwendet. Für dieses Attribut sind die beiden Werte "descendants" und "children" möglich. Der zweite Wert entspricht der Voreinstellung und bezieht sich wie oben genannt auf die unmittelbaren Nachkommen (»Kinder«) des Ursprungselements.

<select-elements from="descendants">

Schlüsselwort Bedeutung
descendants
alle Nachkommen eines Elements
children
der direkter Nachkomme eines Elements (Standardeinstellung)

<rule>
  <target-element type="liste"/>
  <DIV>
    <select-elements from="descendants">
    <target-element type="nachname"/>
    <select-element>
  </DIV>
</rule>

Auf die Verwendung des Befehls <children/> zur Angabe des einzusetzenden Inhalts wird also vollständig verzichtet. Statt dessen wird ein zusätzliches Suchmuster für das einzusetzende Element definiert. Die Struktur der Daten eines XML-Dokuments kann so völlig verändert werden. Anhand der gleichen XML-Daten lassen sich so leicht mit verschiedenen XSL-Stylesheets immer wieder andere Ausgaben erzeugen. Daten müssen also wirklich nur noch einmal in einer XML-Datei eingegeben und verwaltet und nicht für jeden Zweck völlig umgeformt werden.

Das folgende Beispiel filtert aus einer Adressenliste alle Nachnamen und gibt diese aus:

<?xml version="1.0"?>
<liste>
  <adresse>
    <nachname>        Meier        </nachname>
    <telefon>        05656-78789        </telefon>
  </adresse>
  <adresse>
    <nachname>        Müller        </nachname>
    <telefon>        06767-667687        </telefon>
  </adresse>
<liste>

Die zugehörige XSL-Datei:

<xsl>
  <rule>
    <target-element type="liste"/>
    <B>
    <select-elements>
    <target-element type="nachname"/>
    <select-elements/>
    </B>
    <HR/>
  </rule>
</xsl>

Aus beiden Dateien entsteht mithilfe des Parsers ein HTML-Dokument:

<HTML>
  <BODY>
    <B>Meier</B><HR>
    <B>Müller</B><HR>
  </BODY>
</HTML>

6.7 Skriptsprachen

Skriptsprachen, beispielsweise JavaScript, finden in XSL-Stylesheets eine gleiche Funktionalität wie in HTML-Dokumenten. Sie bilden die Basis für eine dynamische Seitengenerierung und interaktive Websites. Man unterscheidet zwei Einsatzarten von Skripten in XSL:

Der Microsoft XSL-Parser unterstützt die Skriptsprache Microsoft JSkript, die eine Zusammenfassung der JavaScript- und ECMAScript-Definitionen bildet. Zusätzlich sind neben den Standardfunktionen von JavaScript einige weitere Funktionen integriert.

6.7.1 Skripte in HTML

Innerhalb der Basis-Konstruktionsregel lassen sich mithilfe eines CDATA-Abschnitts Jscript-Funktionen direkt in das HTML-Dokument übertragen. Der CDATA-Abschnitt sorgt dafür, dass alle in ihm enthaltenen Zeichen ohne weitere Bearbeitung durch den Parser ungeprüft an das Dokument weitergereicht werden. Die Definition der verwendeten Sprache durch den Befehl SCRIPT erfolgt als umschließendes Tag dieses Abschnitts. Er wird verwendet, um dynamische Websites oder so genanntes Dynamic HTML zu generieren.

<rule>
  <root/>
  <HTML>
    <HEAD>
    <SCRIPT LANGUAGE="JSCRIPT">
      <![CDATA[
        var bildan    = new Array();
        var bildaus   = new Array();
        bildan[0]     = new Image();
        bildan[0].src = "images/button1an.gif";
        function an(i) {
          if (i == 0)
          {
            document.images[0].src=bildan[0].src
          }}
        function aus(i) {
          if (i == 0)
          {
            document.images[0].src=bildaus[0].src
          }}
      ]]>
      </SCRIPT>
    </HEAD>
    <BODY>
      <children/>
    </BODY>
  </HTML>
</rule>

Die im Skript definierten Funktionen lassen sich dann in beliebigen Konstruktionsregeln verwenden und aufrufen.

<rule>
  <target-element/>
  <A onMouseOver="an(0)" onMouseOut="aus(0)">
    <children/>
  </A>
</rule>

6.7.2 Globale Definitionen

Neben Skripten, die zur Laufzeit des HTML-Dokuments vom Browser ausgeführt werden, bilden solche, die vom Parser während des Übersetzungsprozesses ausgeführt werden, den zweiten großen Anwendungsbereich von Skriptsprachen in XSL.

Diese während der Verarbeitung durch den Parser ausgeführten Funktionen, werden innerhalb eines <define-script>-Abschnitts definiert, der in der Regel am Anfang des XSL-Dokuments definiert wird. Sie werden verwendet, um den Übersetzungsprozess selbst dynamisch gestalten zu können.

<xsl>
  <define-script>
    <![CDATA[
      ...
    ]]>
  </define-script>
</xsl>

6.7.3 Attributwerte errechnen

Mithilfe von JScript lassen sich die Werte eines Attributs direkt im Quelltext errechnen. Dazu setzt man an die Stelle des ersten Zeichens des Attributs ein Gleichzeichen (»=«) ein. Dann kann man, beispielsweise mithilfe der vier Grundrechenarten, die Schriftgröße eines Fonts festlegen.

<rule>
  <target-element/>
  <P font-size="=3 + 4 - 5 * 6 + 'pt'">
    <children/>
  </P>
</rule>

Im HTML-Dokument erscheint lediglich das kalkulierte Endergebnis der Schriftgröße:

<P STYLE="font-size: 12pt">

6.7.4 Nummerierungen

Automatische Seiten- oder Absatznummerierungen kennen wir heute eigentlich aus jedem noch so simplen Textverarbeitungsprogramm, nur in HTML waren solche Funktionen nicht implementiert oder nur schwer umzusetzen. XSL macht es uns leicht mithilfe eines <eval>-Abschnitts solche Nummerierungen durchzuführen. Zahlreiche eingebaute Funktionen, auf die wir im nächsten Abschnitt im Einzelnen eingehen, helfen uns beispielsweise eine automatisch generierte Seitenzahl einzufügen.

Das <eval>-Element dient in erster Linie dazu funktionelle Ausdrücke und Variablen in Textzeichen umzusetzen. Das Ergebnis einer solchen Anweisung ist also eine Zeichenkette. Neben den vorgegebenen Funktionen können zusätzlich eigene in benutzerdefinierte Funktionen eingesetzt werden. Diese müssen allerdings innerhalb der globalen Definition festgelegt sein. Das <eval>-Element selbst darf nur einen einzeiligen Funktionsaufruf ausführen und nicht zur Definition von Funktionen verwendet werden.

<rule>
  <element type="dokument">
    <target-element type="seite"/>
  </element>
  <P><children/><BR/>
    Seite
    <eval>
      formatNumber (childNumber (this), "1")
    </eval>
  </P>
</rule>

Auf das nachstehende Beispiel setzen wir das obige XSL-Dokument zur Konvertierung in ein HTML-Dokument an:

<!xml version="1.0"!>
<dokument>
  <seite>Inhalt der ersten Seite</seite>
  <seite>Inhalt der zweiten Seite</seite>
  <seite>Inhalt der dritten Seite</seite>
  <seite>Inhalt der vierten Seite</seite>
  <seite>Inhalt der fünften Seite</seite>
</dokument>

Im entstandenen HTML-Quelltext sind die automatischen Seitennummerierungen eingefügt:

<HTML>
  <BODY>
    <P>Inhalt der ersten Seite          <BR>Seite 1</P>
    <P>Inhalt der zweiten Seite          <BR>Seite 2</P>
    <P>Inhalt der dritten Seite          <BR>Seite 3</P>
    <P>Inhalt der vierten Seite          <BR>Seite 4</P>
    <P>Inhalt der fünften Seite          <BR>Seite 5</P>
  </BODY>
</HTML>

6.7.5 XML Object Model

Beim Zugriff auf Informationen oder Inhalte einzelner Elemente wird das so genannte XML Object Model eingesetzt. Innerhalb einer Konstruktionsregel können Informationen über das aktuelle Element mit dem Schlüsselwort this abgefragt werden. Bei einigen Befehlen kann die Funktion direkt aufgerufen werden, auf die Angabe von this wird dabei dann verzichtet. Im Einzelnen handelt es sich bei den vorliegenden Funktionen um Variablen, die Auskunft über Elemente der Baumstruktur der Flow Objects des Dokuments geben.

Abb. 6.40: Eltern-Kind-Beziehungen innerhalb eines Dokuments

<xml>
  <liste>
    <adresse>
      <nachname>        Müller      </nachname>
      <vorname>        Wilhelm      </vorname>
    </adresse>
    <adresse>
      <nachname>        Meier      </nachname>
      <vorname>        Claudia      </vorname>
    </adresse>
  </liste>
</xsl>

In unserem Beispiel ist <liste> das Elternelement (parent) oder der Vorgänger von <adresse>. Dieser hat die zwei Nachkommen <nachname> und <vorname>. <nachname> und <vorname> sind zwei Kindelemente (children) auf gleicher Ebene, sie stehen also in einer Geschwister-Beziehung (siblings).

Um auf einzelne Elemente oder Attribute dieses Beziehungsgeflechts zurückgreifen zu können, existieren einige vorgegebene Befehle. Der Befehl tagName beispielsweise liefert uns als Ergebnis den Namen des Markups. Die Befehle finden sich in einer <eval>-Anweisung wieder und beziehen sich auf das in der Konstruktionsregel angegebene Zielelement.

<rule>
  <target-element type="nachname">
  <DIV>
    <eval>tagName</eval>
  </DIV>
</rule>

In unserem Beispiel liefert uns die oben angegebene Konstruktionsregel als Ergebnis die Namen der Markups auf die das Target-Element zutrifft. In diesem Fall entspricht der Tag-Name also dem Zielelement:

<DIV>nachname</DIV>
<DIV>nachname</DIV>

Wesentlich mehr Sinn macht dieses Beispiel, wenn wir nach dem Vorgänger von <nachname> suchen. Dazu fügen wir vor dem tag-name noch den Zusatz parent ein.

<eval>parent.tagName</eval>

Diese so veränderte Konstruktionsregel liefert uns nun den Namen der Vorgängerelemente aller mit <nachname> ausgezeichneten Markierungen:

<DIV>adresse</DIV>
<DIV>adresse</DIV>

children

Liefert alle Nachkommen des ausgewählten Elements.

Parameter: keine

Beispiel: <eval>children</eval>

getAttribute

Gibt den Wert

Parameter: (AttributName)

Beispiel: <eval>getAttribut("height")</eval>

AttributName Name des Attributs.

item

Mit diesem Befehl lässt sich der Inhalt einzelner Elemente einer Aufzählung abrufen. Als Parameter wird entweder der Index des Elements, der Name des ElementTyps oder eine Verbindung beider Parameter angegeben.

Parameter: (Index | ElementTyp | ElementTyp, Index)

Beispiel: <eval>this.children.item(0)</eval>

Index Die Nummer des Elements.

ElementTyp Alternativ der Name des Elements.

In unserem Beispiel finden sich ausgehend vom Element <adresse> die Items <nachname> und <vorname>. Um die Bezeichnung eines Elements zu erfahren, kann zusätzlich tagName an den Befehl angefügt werden. Ohne Angabe eines weiteren Attributs werden alle Informationen des Elements ausgegeben.

<rule>
  <target-element type="adresse">
  <DIV>
    <eval>this.children.item(1).tagName</eval>
  </DIV>
</rule>

Die Nummerierung der Items beginnt bei "0" und nicht bei "1". Daher erhalten wir als Ergebnis unserer Konstruktionsregel folgenden HTML-Quelltext:

<DIV>vorname</DIV>
<DIV>vorname</DIV>

Abb. 6.41: Wird kein weiteres Attribut angegeben, werden alle Informationen über das Element angezeigt.

Alternativ zur Anzeige des TagNames kann auch der Inhalt des Elements über den Zusatz text ausgegeben werden:

<rule>
  <target-element type="adresse">
  <DIV>
    <eval>this.children.item(1).text</eval>
  </DIV>
</rule>

Das Ergebnis des oben gezeigten XSL-Dokuments ist die Anzeige der Vornamen unseres Beispiels.

<DIV>Wilhelm</DIV>
<DIV>Claudia</DIV>

length

Um die Anzahl der Elemente einer Auflistung zu erfahren, verwenden Sie diesen Befehl:

Parameter: keine

Beispiel: this.children.length

parent

Gibt den Vorgänger eines Elements wieder.

Parameter: keine

Beispiel: parent.item(0)

tagName

Gibt den Namen eines Elements aus.

Parameter: keine

Beispiel: tagName

text

Gibt den Inhalt eines Elements, also den Text der sich zwischen den beiden Markups des Befehls befindet.

Parameter: keine

Beispiel: children.text

6.7.6 Zugriff auf Elemente

ancestor

Gibt den nächsten Vorfahren eines Elements zurück. Sofern keine direkten Vorfahren existieren, gibt die Funktion den Wert Null zurück.

Parameter: (ElementTyp, Element)

Beispiel: ancestor("nachname", this)

ElementTyp Der ElementTyp des gesuchten Vorgängers.

Element Das Element bei dem die Suche starten soll. Das Schlüsselwort "this" gibt an, dass die Suche in dem von <target-element> beschriebenen Element beginnen soll.

ancestorChildNumber

Gibt die Anzahl der direkten Nachkommen eines Elements wieder. Sollte es keinen Nachfolger geben, ist das Ergebnis der Funktion Null.

Parameter: (ElementTyp, Element)

Beispiel: ancestorChildNumber("nachname", this)

ElementTyp Der ElementTyp des gesuchten Vorgängers.

Element Das Element bei dem die Suche starten soll.

childNumber

Die Funktion gibt die Anzahl der Geschwisterelemente eines Elements aus. Also alle Elemente, die mit dem gesuchten Element auf einer hierarchischen Stufe stehen und dem gleichen Vorgänger angehören.

Parameter: (Element)

Beispiel: childNumber(this)

Element Das Element dessen Anzahl an Geschwistern gesucht ist.

formatNumber

Tauscht eine Zahl gegen eine Zeichenkette aus. Durch die Wahl zwischen sechs verschiedenen Formaten lässt sich die Ausgabe variieren.

Parameter: (Nummer, Format)

Beispiel: formatNumber(childNumber(this), "A")

Nummer Die Nummer, die in eine Zeichenkette umgewandelt werden soll.

Format Das Ausgabeformat.

Format Bedeutung
"1"
0, 1, 2, 3, ...
"01"
0, 01, 02, 03, 04, ...
"001"
0, 001, 002, 003, 004, ...
"0001"
0, 0001, 0002, 0003, 0004, ...
"a"
0, a, b, c, d, ...
"A"
0, A, B, C, D, ...
"i"
0, i, ii, iii, iv, ...
"I"
0, I, II, III, IV, ...

Der erste Wert in der Reihe bleibt immer Null, unabhängig vom gewählten Typ.

formatNumberList

Wandelt eine Liste von Zahlen in ein Ausgabeformat um. Dieser Befehl wird eingesetzt, um beispielsweise eine Kapitelgliederung (»5.2.8«) zu generieren.

Parameter: (Liste, Format, Trennzeichen)

Beispiel: formatNumberList(path(this), "1", ".")

Liste Die Zahlenliste, die ausgegeben werden soll.

Format Es gelten die gleichen Formateinstellungen, wie für FormatNumber.

Trennzeichen Zwischen den einzelnen Zahlen wird ein Trennzeichen eingefügt. In der Regel ein Punkt oder Strich.

<rule>
  <target-element type="kapitel">
  <DIV>
    <eval>formatNumberList(path(this), "1", ".")</eval>
    <children/>
  <DIV>
</rule>

hierarchicalNumberRecursive

Gibt eine Zahlenliste zurück, die die Anzahl der Geschwister und Eltern und deren Vorgänger usw. repräsentiert. Diese Funktion wird vor allem dazu verwendet, um eine automatische Nummerierung der einzelnen Kapitel oder Absätze eines Dokument zu erreichen.

Parameter: (ElementTyp, Element)

Beispiel: hierarchicalNumberRecursive("kapitel", this)

ElementTyp Das Wurzelelement bis zu dem der Pfad verfolgt werden soll.

Element Das Ende des Pfads, dass bis zum ersten Wurzelelement verfolgt wird, muss angegeben werden.

<rule>
  <target-element type="titel">
  <DIV>
    <eval>
      formatNumber
      hierarchicalNumberRecursive("kapitel", this), "1", "/")
    </eval>
    <children/>
  </DIV>
</rule>

path

Die Funktionsweise ist sehr ähnlich zu hierachicalNumberRecursive, mit dem Unterschied, dass hier der komplette Pfad verfolgt wird und nicht nur die Nachkommen des Elements. Die Anzahl der Zahlen in der Liste gibt gleichzeitig auch die Tiefe der Dokumentenstruktur wieder.

Parameter: (Element)

Beispiel: path(this)

Element Das Ende des Pfads, dass bis zum ersten Wurzelelement verfolgt wird, muss angegeben werden.

Auf unser Beispiel übertragen bedeutet diese Nummerierung der einzelnen Elemente:

(1)        <liste>
(1, 1)         <adresse>
(1, 1, 1)        <nachname>
(1, 1, 2)        <vorname>
(1, 2)        <adresse>
(1, 2, 1)        <nachname>
(1, 2, 2)        <vorname>

Zur Ausgabe einer solchen Zahlenliste wird in der Regel der Befehl formatNumberList verwendet.

6.8 Referenz XSL

Der folgende Abschnitt enthält eine komplette Kurzreferenz aller relevanten XSL-Befehle. Er soll als Referenz dienen und enthält daher nur eine kurze Beschreibung der einzelnen Elemente und Attribute. Sie finden alle Befehle in alphabetischer Reihenfolge sortiert:

Befehl <?xml:stylesheet?>
Attribute href type
Bedeutung Verbindet ein XML- oder HTML-Dokument mit einem Stylesheet.

Der Befehl verweist entweder auf ein Cascading Style Sheet oder ein XSL-Stylesheet.

Beispiele:

<?xml:stylesheet href="kunden.css" type="text/css"?>
<?xml:stylesheet href="kunden.xsl" type="text/xsl"?>

Befehl <any>
Attribute keine
Bedeutung Um alle Nachkommen des Zielelements zu berücksichtigen kann dieser Befehl eingesetzt werden.

Beispiel:

<element type="document">
  <any>
    <target-element/>
  </any>
</element>

Befehl <apply>
Attribute alle Stylesheet-Definitionen
Bedeutung Wendet die angegebenen Stilauszeichnungen auf die Zielelemente an.

Beispiel:

<apply font-style="bold"/>
<apply font-size="12pt"/>

Befehl <attribut>
Attribute name value has-value
Bedeutung Ergänzt das Suchmuster einer Konstruktionsregel um eine näheren Vergleich der Attribute eines Elements.

Beispiele:

<attribut name="attribut" value="wert"/>
<attribut name="attribut" has-value="no">
<attribut name="attribut" has-value="yes">

Befehl <![CDATA[ ... ]]>
Attribute keine
Bedeutung Übernimmt die eingeschlossene Zeichenmenge ohne weitere Bearbeitung durch den Parser in das Zieldokument.
Befehl <children/>
Attribute keine
Bedeutung Gibt an wo in der Aktionsanweisung das Element, das mit dem Muster der Konstruktionsregel übereinstimmt, eingesetzt werden soll.

Dieser Befehl ist ein leeres Element und wird daher in der Form <children/> eingesetzt.

Befehl <define-script>
Attribute Keine
Bedeutung Dient der Definition eines Skripts, das vom Parser zur Übersetzungszeit ausgeführt wird. Es ermöglicht so eine dynamische Generierung des Zieldokuments.

In der Regel wird <define-script> im Zusammenhang mit einem CDATA-Abschnitt eingesetzt:

<define-script>
  <![CDATA
  [
    ...
  ]]>
</define-script>

Befehl <element>
Attribute Type
Bedeutung Ermöglicht die nähere Eingrenzung des Musters durch Angabe des übergeordneten Elements in dem sich das target-element befinden muss.

Beispiel:

<element type="element">

Befehl <eval>
Attribute Keine
Bedeutung Das <eval>-Element dient in erster Linie dazu funktionelle Ausdrücke und Variablen in Textzeichen umzusetzen.
Befehl <import>
Attribute Href
Bedeutung Importiert ein Stylesheet zur Übersetzungszeit in ein anderes XSL-Stylesheet.

Beispiel:

<import href="kunden.xsl"/>

Befehl <root/>
Attribute Keine
Bedeutung Kennzeichnet eine Basis-Konstruktionsregel. Diese dient der Angabe der HTML-Grundstruktur des Dokuments. Alle weiteren Elemente werden in diese Struktur eingefügt.

Beispiel:

<rule>
  <root/>
  <HTML>
    <HEAD>
      <TITLE>Neue Seite</TITLE>
    </HEAD>
    <BODY>
      <children/>
    </BODY>
  </HTML>
</rule>

Befehl <rule>
Attribute Keine
Bedeutung Kennzeichnet eine Konstruktionsregel.

Beispiel:

<rule>
  <target-element type="adresse">
  <DIV>
    <children/>
  </DIV>
</rule>

Befehl <select-elements>
Attribute From
Bedeutung Das Tag <select-elements>, das sich innerhalb des Aktion-Abschnitts befindet ersetzt das <children/>-Element. Es ergänzt XSL um die Funktion zum Herausfiltern von Elementen.

Beispiel:

<select-elements from="descendants">
</select-elements>

<select-elements from="children">
</select-elements>

Schlüsselwort Bedeutung
descendants
alle Nachkommen eines Elements
children
der direkte Nachkomme eines Elements (Standardeinstellung)
Befehl <style-rule>
Attribute Keine
Bedeutung Mit dem Markup <style-rule> werden die so genannten Stilregeln festgelegt. Diese übertragen Cascading Style Sheets auf einzelne Elemente.

Beispiel:

<style-rule>
  <target-element/>
  <apply font-style="bold"/>
</style-rule>

Befehl <target-element>
Attribute Type Position Only
Bedeutung Definiert innerhalb einer Konstruktionsregel das Muster, auf das die Aktion durchgeführt werden soll. Das Zielelement ist zwar fester Bestandteil einer Konstruktionsregel, es muss aber kein weiteres Attribut enthalten.

Beispiel:

<target-element type="liste"/>
<target-element/>
<target-element type="liste" position="first-of-type"/>

Schlüsselwort Bedeutung
first-of-type
Erster Nachkomme eines Elements dieses Typs.
last-of-type
Letzter Nachkomme eines Elements dieses Typs.
first-of-any
Erster Nachkomme eines Elements beliebigen Typs.
last-of-any
Letzter Nachkomme eines Elements beliebigen Typs.

Beispiel:

<target-element type="liste" only="of-type">
<target-element type="liste" only="of-any">
<target-element type="liste" only="first-of-any">
<target-element type="liste" only="last-of-any">

Schlüsselwort Bedeutung
of-type
es existiert nur ein Nachkomme des definierten Typs
of-any
es existiert nur ein Nachkomme eines beliebiges Typs
Befehl <xsl>
Attribute Keine
Bedeutung Legt den Anfang und das Ende eines XSL-Dokuments fest und gehört somit zwingend zur Grundstruktur des Stylesheets.

Die folgenden Befehle sind beschrieben in der W3C-Definition XSL Transformations (XSLT) vom 16.11.1999. Die so genannte XSLT beschreibt eine Reihe von Befehlen, die die Umsetzung von XML-Dokumenten in andere (XML-)Formate ermöglichen.

Befehl <xsl:apply-imports>
Bedeutung Wählt den aktuellen Knoten und jeden Nachkommen dieses Knotens aus, indem die importierten Stylesheet-Definitionen verwendet werden.

Beispiele:

<xsl:template match="abschnitt">
<xsl:apply-imports/>
</xsl:template>

Befehl <xsl:apply-templates>
Bedeutung Legt den unmittelbaren Vorgänger (children) des Quellelements fest, der zunächst bearbeitet werden soll.

Beispiele:

<xsl:template match="abschnitt">
<xsl:apply-imports/>
</xsl:template>

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

Befehl <xsl:arg>
Bedeutung Mithilfe dieses Befehls lässt sich ein Argument und der zugehörige Vorgabewert für eine Variable festlegen. Eingesetzt wird diese Funktion zum Beispiel, um den Startwert für ein Makro anzugeben.

Beispiele:

<xsl:macro name="Seitennumerierung">
<xsl:macro-arg name="Seite" default="1"/>
<xsl:number Seite="{arg(Seite)}"/>
<xsl:contents/>
</xsl:macro>

<xsl:template match="Eintrag">
<xsl:invoke macro="Seitennumerierung">
<xsl:arg name="Seite" default="16">
<xsl:apply-templates/>
</xsl:invoke>
</xsl:template>

Befehl <xsl:attribute>
Bedeutung Im Ergebnisbaum kann mit diesem Befehl einem Element ein Attribut hinzugefügt werden.

Beispiele:

<xsl:element name="adresse">
<xsl:attribute name="staat">Deutschland</xsl:attribute>
</xsl:element>

Befehl <xsl:attribute-set>
Bedeutung Ermöglicht es eine Reihe von Formatauszeichnungen einem Element zuzuweisen.

Beispiele:

<xsl:attribute-set name="h1 "
  font-size="18pt"
  font-family="Arial"/>

<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>

Befehl <xsl:choose>
Bedeutung Dieser Befehl erlaubt es Ihnen ähnlich wie xsl:if eine bedingte Auswahl zu treffen. Anders als bei xsl:if besteht dabei nicht nur die Möglichkeit eine einzelne Auswahl zu treffen (also: wenn (a) dann (b)), sondern eine ganze Reihe von Vergleichen anzustellen (also: wenn (a) dann (b); wenn (c) dann (d); sonst (e)).

Beispiele:

<xsl:choose>
  <xsl:when test=".[first-of-type()]">
    First-Of-Type
  </xsl:when>
  <xsl:when test=".[last-of-type()]">
    Last-Of-Type
  </xsl:when>
  <xsl:when test=".[last-of-any()]">
    Last-Of-Any
  </xsl:when>
  <xsl:otherwise>
    Der Rest ...
  </xsl:otherwise>
</xsl:choose>

Befehl <xsl:comment>
Bedeutung Fügt einen beliebigen Kommentar in ein XML-Dokument ein. Nach der Bearbeitung wird dieser in üblicher Schreibweise dem XML-Dokument eingefügt:
<!-- Hier steht der Kommentar -->

Beispiele:

<xsl:comment>
  Hier steht der Kommentar ...
</xsl:comment >

Befehl <xsl:constant>
Bedeutung Mit diesem Befehl definieren Sie eine beliebige Konstante, auf die Sie später zurückgreifen können.

Beispiele:

<xsl:constant name="jahr" value="2000"/>

Befehl <xsl:contents>
Bedeutung Bestimmt innerhalb eines Makros die Position, an der bei der Ausführung des Makros der Inhalt des xsl:invoke-Befehls eingefügt wird.

Beispiele:

<xsl:macro name="seite">
  Seitennummer:
  <xsl:contents/>
</xsl:macro>

Befehl <xsl:copy>
Bedeutung Erlaubt es alle passenden Nodes innerhalb des Abschnitts in das XML-Dokument zu kopieren. So lässt sich beispielsweise HTML-Quelltext direkt im XSL-Dokument formulieren.

Beispiele:

<xsl:copy>
  <xsl:apply-templates/>
</xsl:copy>

Befehl <xsl:counter>
Bedeutung Richtet einen Zähler ein. Dieser Zähler muss zunächst mit xsl:counter-reset initialisiert und kann dann jeweils mit xsl:counter-increment erhöht werden.

Beispiele:

<xsl:counter-reset name="seite"/>

<xsl:counter name="seite"/>
<xsl:counter-increment name="seite"/>

Befehl <xsl:counter-increment>
Bedeutung Erhöht den definierten Zähler inkrementell.

Beispiele:

<xsl:counter name="seite"/>
<xsl:counter-increment name="seite"/>

Befehl <xsl:counter-reset>
Bedeutung Setzt den Zähler zurück und initialisiert ihn.

Beispiele:

<xsl:counter-reset name="seite"/>

Befehl <xsl:element>
Bedeutung Fügt ein ausgewähltes Element in das XML-Dokument ein.

Beispiele:

<xsl:element name="buch">
  <xsl:element name="kapitel">
    <xsl:text>
      Einführung in XSL
    </xsl:text>
  </xsl:element>
</xsl:element>

Befehl <xsl:for-each>
Bedeutung Wählt eine beliebige Anzahl gleicher Elemente aus.

Beispiele:

<adressbuch>
  <adresse>
    <name>Meier</name>
    <telefon>05252-5678778</telefon<
  </adresse>
  <adresse>
    <name>Müller</name>
    <telefon>05252-787182</telefon<
  </adresse>
</adressbuch>

<xsl:template match="adresse">
  <ol>
    <xsl:for-each select="adresse">
      <li>
        <xsl:process select="name">
      </li>
    </xsl:for-each>
  </ol>
</xsl:template>

<ol>
  <li>Meier</li>
  <li>Müller</li>
</ol>

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

Befehl <xsl:if>
Bedeutung Mit diesem Befehl realisieren Sie eine einfache bedingte Auswahl nach dem Schema wenn (a), dann (b) sonst (c). In unserem Beispiel wird so lange ein »und« ausgegeben bis der letzte Eintrag erreicht ist.

Beispiele:

<xsl:template match="kapitel">
  <xsl:apply-templates/>
  <xsl:if test=".not([last-of-any()])">
    und
  </xsl:if>
</xsl:template>

Befehl <xsl:import>
Bedeutung Gibt eine externe XSL-Stylesheet-Definition an. Diese wird in die aktuelle XSL-Definition importiert. Dieser Befehl sollte am Anfang des Dokuments eingefügt werden.

Beispiele:

<xsl:import href="http://www.domain.de/style.xsl">
<xsl:import href=" style.xsl">

<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>

Befehl <xsl:macro>
Bedeutung Mit dem Befehl xsl:macro lassen sich wiederverwendbare Funktionen oder Prozeduren für eine XSL-Datei erstellen. Über das xsl:invoke-Element lässt sich das Makro beliebig häufig aufrufen.

Beispiele:

<xsl:macro name="Seitennumerierung">
  <xsl:macro-arg name="Seite" default="1"/>
  <xsl:number Seite="{arg(Seite)}"/>
  <xsl:contents/>
</xsl:macro>

<xsl:template match="Eintrag">
  <xsl:invoke macro="Seitennumerierung">
    <xsl:arg name="Seite" default="16">
    <xsl:apply-templates/>
  </xsl:invoke>
</xsl:template>

Befehl <xsl:macro-arg>
Bedeutung Definiert ein Argument, das an ein Makro übergeben werden soll. Optional kann dem Argument zusätzlich ein Wert vorgegeben werden.

Beispiele:

<xsl:macro name="seite">
  <xsl:macro-arg name="abschnitt" default="1"/>
  <xsl:contents/>
</xsl:macro>

Befehl <xsl:number>
Bedeutung Diese Funktion führt eine automatische Nummerierung der Elemente durch.

Beispiele:

<xsl:template match="kapitel">
  <xsl:number level="any" from="kapitel" count="absatz">
  <xsl:text>-</xsl:text>
</xsl:template>

Befehl <xsl:otherwise>
Bedeutung Gibt die »sonst«-Anweisung für eine xsl:choose-Auswahl an. Trifft keine der angegebenen Bedingungen zu, dann wird automatisch der mit xsl:otherwise definierte Abschnitt ausgeführt.

Beispiele:

<xsl:choose>
  <xsl:when test=".[first-of-type()]">
    First-Of-Type
  </xsl:when>
  <xsl:when test=".[last-of-type()]">
    Last-Of-Type
  </xsl:when>
  <xsl:otherwise>
    Der Rest ...
  </xsl:otherwise>
</xsl:choose>

Befehl <xsl:pi>
Bedeutung Fügt eine Processing Instruction (PI) in das XML-Dokument ein.

Beispiele:

<xsl:pi name="xml">
  version="1.0"
</xsl:pi>

<?xml version="1.0"?>

Befehl <xsl:preserve-space>
Bedeutung Analog zum Befehl xml:space="preserve" ändert dieser Befehl die Einstellungen für die Behandlung von Leerraum (whitespace). Der gesamte Leerraum, der sich im Inhalt des angegebenen Elements befindet, wird unverändert an die Anwendung weitergegeben.

Beispiele:

<xsl:preserve-space element="source"/>

Befehl <xsl:strip-space>
Bedeutung Im Gegensatz zum vorangegangenen Befehl, bewirkt diese Einstellung genau das Gegenteil: der gesamte Leerraum innerhalb eines Elements wird entfernt. Dieser Befehl ist analog zum XML-Befehl xml:space="default".

Beispiele:

<xsl:strip-space element="source"/>

Befehl <xsl:template>
Bedeutung Dieser Befehl wählt ein bestimmtes Element aus, das über das Attribut match näher spezifiziert wird.

Beispiele:

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

Befehl <xsl:text>
Bedeutung Fügt den Inhalt des Elements als einen beliebigen Text an der angegebenen Position im XML-Dokument ein.

Beispiele:

<xsl:text>
  Hier wird ein beliebiger Text eingefügt ...
</xsl:text>