XSLT-Elemente
(Auszug aus "Python & XML" von Christopher A. Jones & Fred L. Drake, Jr.)
Viel von der XSLT-Funktionalität erschließt sich in Form von Elementen, die gewisse Funktionen ausführen oder Aufgaben erledigen. Tatsächlich basiert die gesamte Sprache auf XML, und die Beschreibung ihrer Eigenschaften ist bereits Gegenstand mehrerer Bücher. Dieser Abschnitt stellt einige der XSLT-Elemente und -Grundlagen vor, damit Sie anfangen können, es bei Ihrer täglichen Arbeit einzusetzen.
Das Stylesheet-Element
Das xsl:stylesheet-Element ist immer das Wurzelelement von eigenständigen Stylesheets und wird auch bei eingebetteten Stylesheets benutzt. Das stylesheet-Element enthält einige optionale und notwendige Attribute, die dem XSLT-Prozessor mehr Details über das Stylesheet angeben. Die Spezifikation definiert ein zweites Wurzelelement im XSLT-Namensraum namens xsl:transform. Dieses Element ist mit xsl:stylesheet in jeder Hinsicht außer im Namen identisch und kann ohne jede Bedeutungsänderung anstelle von xsl:stylesheet verwendet werden.
Das id-Attribut ist optional. Ein Bezeichner wäre jedoch sicher praktisch, wenn dieses Stylesheet Teil eines größeren XML-Dokuments wäre (was bei einem eingebetteten Stylesheet der Fall wäre). Die XML-Spezifikation besagt, daß jedes Attribut vom Typ ID (das nicht unbedingt id heißen, aber in der DTD als vom Datentyp ID deklariert sein muß) in jedem XML-Dokument eindeutig sein muß. Die Verwendung eines ID-Attributs auf einem Stylesheet ist ein mächtiges Instrument, wenn Sie dynamisch mehrere Stylesheets erzeugen, die in einem größeren zusammengesetzten Dokument gemeinsam verwendet werden.
Das Attribut version wird benötigt, da es angibt, welche Version von XSLT benutzt wird. Alle xsl:stylesheet-Elemente müssen das version-Attribut haben. Im Wurzelelement von vereinfachten Stylesheets muß ebenfalls ein version-Attribut explizit mit dem XSLT-Namensraum assoziiert sein, wie im Beispiel ships-template.html gezeigt.
Es wird wärmstens empfohlen, daß Sie den Stylesheet-Elementen ein Namensraumpräfix geben, um sie von anderen Elementen zu unterscheiden, die Teil der Transformation oder Teil eines größeren Dokuments sind, das das Stylesheet enthält. Der URI des Namensraums muß der W3C-URI "http://www.w3.org/1999/XSL/Transform" sein.
Ein typisches Stylesheet-Element kann etwa so beginnen:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
In diesem Beispiel werden der Namensraum und die Version angegeben, aber es ist kein id-Attribut vorhanden.
Da XSLT eine Ausgabe erzeugen kann, die XML, HTML oder irgendein anderes Format haben kann, ist es wichtig anzugeben, welche Form die Ausgabe haben sollte. Dies wird mit dem Element xsl:output getan, das ein einziges Attribut benötigt:
<xsl:output method="xml"/>
Der Wert des Attributs method kann xml, html oder text sein. Die Bedeutung jedes Wertes entspricht ungefähr dem, was Sie erwarten würden. Falls die Ausgabe XHTML sein sollte, verwenden Sie den Wert xml. Bei allen Formaten, die weder XML noch HTML sind, erlaubt der Wert text eine Kontrolle über jedes Byte der Ausgabe, aber die beabsichtigte Verwendungsweise ist die, textbasierte Formate zu erzeugen. Wenn Sie Formate wie RTF oder irgendeine der TeX-basierten Sprachen erzeugen möchten, ist text der korrekte Wert, den Sie benutzen sollten. Viele Anwendungen, die andere Formate benötigen, können dadurch zufriedengestellt werden, daß man ein XSL-FO-Dokument erzeugt und dieses dann mit einem Prozessor bearbeitet, der über eine Menge Informationen über die Details des Zielformates verfügt. (Es gibt jedoch auch Python-Produkte, die Binärformate wie PDF völlig ohne Stylesheets und/oder XSL-FO aus einem XML-Dialekt erzeugen können. Siehe dazu ReportLab - Content to PDF Solutions – Anm. d. Ü.)
Wenn das Stylesheet kein xsl:output-Element enthält oder wenn das method-Attribut nicht angegeben ist, ist die Ausgabe XML.
Erzeugen eines Vorlagen-Elements
Das Element xsl:template wird regelmäßig zur Verrichtung einer ganzen Menge Arbeit im Transformationsprozeß benutzt. Dieses Element ist eine XSLT-Anweisung und gibt normalerweise ein Muster für seinen Aufruf an oder definiert einen Namen, damit es von anderen Teilen des XSL-Dokuments aufgerufen werden kann. Der Rumpf des Elements xsl:template enthält die Auszeichnungen für die Ausgabe, wann immer die Vorlage vom XSLT-Prozessor aufgerufen oder verglichen wird.
Die Attribute des Vorlagen-Elements definieren optional dessen Namen (name) und Vergleichsregel (match). Weiterhin verfügbar sind ein Modus (mode) und eine Priorität (priority). Mit dem Modus wird ein Namensraumpräfix angegeben, das vom XSLT-Prozessor berücksichtigt werden soll, wenn die Anweisung xsl:apply-templates (die im nächsten Abschnitt erklärt wird) mit einem speziellen Modus verwendet wird. Das priority-Attribut definiert eine Priorität, falls die Vorlage Teil einer Sammlung von Vorlagen-Elementen ist, die auf das gleiche Muster passen. Mit anderen Worten: Wenn der XSLT-Prozessor aus verschiedenen Vorlagen wählen kann, verwendet er priority, falls angegeben.
Das wichtigste Attribut hierbei ist match. Das match-Attribut enthält einen XPath-Ausdruck, mit dem bestimmt wird, wann der Prozessor das Zielelement im XML-Dokument gefunden hat. Statt etwa wie im früheren Adreßdatensatz-Beispiel das Dokument mit SAX zu parsen und auf Ihr Ereignis zu warten, können Sie mit dem folgenden match-Attribut und der XPath-Syntax die erste Adreßzeile ausfindig machen:
<xsl:template match="/addr-record/address1">
Dieser Ausdruck beginnt mit dem Wurzelelement addr-record und wählt dann dessen Kind address1 aus. Um den Inhalt dieses Felds anzuzeigen, könnten Sie den gleichen Ausdruck in Ihrem select-Attribut benutzen (was ein wenig später in diesem Abschnitt gezeigt wird).
Zuvor haben wir ein Vorlagen-Element erzeugt, um ein komplettes XML-Dokument zu vergleichen und ein vollständiges HTML-Dokument zu produzieren. Sie können die Vorlagen-Elemente auch benutzen, um irgendein Element innerhalb des XML-Eingabedokuments zu vergleichen:
<xsl:template match="/addr-record/address1">
<html>
<head>
<title>Transformierter Satz von Adressen</title>
</head>
<body>
<p>Wir haben /addr-record/address1 verwendet</p>
<p><xsl:value-of select="/addr-record/address1"/></p>
</body>
</html>
</xsl:template>
In diesem Beispiel vergleichen Sie ein Element address1, das ein Kind des Wurzelelements addr-record ist, um anschließend mehrere Regeln und den Inhalt zu bearbeiten. Wenn die Vorlage vom XSLT-Prozessor instanziiert wird, gibt er die Kindelemente der Vorlage aus (in diesem Fall HTML) und bearbeitet alle weiteren darin enthaltenen XSLT-Elemente. Das Ergebnis ist, daß der HTML-Code vom XSLT-Prozessor auf die Standardausgabe geschrieben wird. Wenn Sie diese modifizierte Version des Stylesheets auf dem XML-Dokument ausführen, erhalten Sie das im vorherigen Code-Listing erwartete HTML, aber Sie bekommen auch den Rest der Zeichendaten des XML-Dokuments hinter dem HTML. Das liegt daran, daß für den Rest der Zeichendaten keine Anweisungen angegeben wurden, und daher werden diese einfach ausgespuckt. Das Element xsl:apply-templates ermöglicht es Ihnen, Regeln ineinander zu verschachteln, um tiefverschachtelte Dokumente zu produzieren, die wie erwartet transformiert werden.
Anwenden von Vorlagen
Wenn Sie ein Dokument haben, das verschachtelte Strukturen enthält, wird das Element apply-templates dazu benutzt, die Transformationsregeln rekursiv im gesamten Dokument anzuwenden. Ein einfaches Beispiel, das das Konzept von verschachtelten Strukturen demonstriert, ist formatierter Text, in dem zum Beispiel Absätze mit Sätzen in fetter Schriftart und mehreren Farben, mit Codebeispielen oder anderen Formatierungsstrukturen enthalten sein dürfen, die ineinander verschachtelt vorkommen dürfen.
Eine andere tiefverschachtelte Struktur ist ein Dateisystem. Ein Verzeichnis kann eine beliebige Anzahl von Dateien und Unterverzeichnissen enthalten. Jedes Unterverzeichnis folgt der gleichen Inhaltsregel wie jedes andere Unterverzeichnis und darf beliebig viele Dateien und Unterverzeichnisse enthalten. Der resultierende Baum kann ziemlich komplex werden.
Bei XML-Dokumenten mit verschachtelten Strukturen kann es wünschenswert sein, eine Menge von Regeln (Vorlagen) für bestimmte Tags aufzustellen, aber auch die Verschachtelung dieser Tags und Regeln ineinander zu erlauben. Das können Sie mit apply-templates-Elementen erreichen. Betrachten Sie folgendes XML:
<deep-nest>
<title>Sample Text</title>
<big>T</big>his is an example of
<red>Fancy Text</red> that comes in
<blue>m<big>u</big></blue><green>l<big>
t</big></green><blue>i<big>p</big>
</blue><green>l<big>e</big></green>
colors. Many of <bold>these</bold>
elements are <big><green>N</green>
<blue>E</blue><green>S</green><blue>T</blue>
<green>E</green><blue>D</blue></big> within
each other.
</deep-nest>
Dieses XML-Fragment enthält Elemente, die andere Elemente enthalten. Es gibt keine festgelegte Ordnung, die besagt, welche Tags in andere eingebettet werden können, da keine DTD definiert ist. Um diese Verschachtelung in Ihren Vorlagen-Elementen zu berücksichtigen, benutzen Sie die xsl:apply-templates-Anweisung. Das Element big kann z. B. in einem color-, einem bold- oder einem title-Element vorkommen. Daher lautet sein template-Element:
<xsl:template match="big">
<font size="5"><xsl:apply-templates/></font>
</xsl:template>
Wo auch immer es ein big-Element gibt, wird es mit dem font-Tag ersetzt. Außerdem wird der gesamte Inhalt des big-Elements mit allen anderen Vorlagenmustern verglichen, da die Anweisung xsl:apply-templates angegeben wird. Sehen wir uns nun das komplette Stylesheet an, mit dem das XML verarbeitet wird:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="deep-nest">
<html><body><xsl:apply-templates/></body></html>
</xsl:template>
<xsl:template match="title">
<h1><xsl:apply-templates/></h1>
</xsl:template>
<xsl:template match="big">
<font size="5"><xsl:apply-templates/></font>
</xsl:template>
<xsl:template match="red">
<font size="3" color="#FF0000"><u><xsl:apply-templates/></u></font>
</xsl:template>
<xsl:template match="blue">
<font color="#0000FF"><xsl:apply-templates/></font>
</xsl:template>
<xsl:template match="green">
<font color="#00FF00"><b><xsl:apply-templates/></b></font>
</xsl:template>
<xsl:template match="bold">
<b><i><xsl:apply-templates/></i></b>
</xsl:template>
</xsl:stylesheet>
Das Wichtigste an diesem Stylesheet ist seine Wohlgeformtheit. Jedem XML-Element im Quelldokument wird im Stylesheet Rechnung getragen, und jedes wird wunschgemäß weiterverarbeitet, indem xsl:apply-templates mitten hinein gesetzt wird. Wenn Sie das XML und das Stylesheet an Ihren XSLT-Prozessor übergeben, bekommen Sie folgendes HTML:
<html>
<body>
<h1>Sample Text</h1>
<font size='5'>T</font>his is an example of
<font color='#FF0000' size='3'>
<u>Fancy Text</u>
</font> that comes in
<font color='#0000FF'>m<font size='5'>u</font>
</font>
<font color='#00FF00'>
<b>l<font size='5'>
t</font></b>
</font>
<font color='#0000FF'>i<font size='5'>p</font>
</font>
<font color='#00FF00'>
<b>l<font size='5'>e</font></b>
</font>
colors. Many of <b><i>these</i></b>
elements are <font size='5'>
<font color='#00FF00'>
<b>N</b>
</font>
<font color='#0000FF'>E</font>
<font color='#00FF00'>
<b>S</b>
</font>
<font color='#0000FF'>T</font>
<font color='#00FF00'>
<b>E</b>
</font>
<font color='#0000FF'>D</font>
</font> within
each other.
</body>
</html>
Zugriff auf den Wert eines Knotens
Das Element xsl:value-of generiert eine Ausgabe aus einem Ausdruck. Es hat zwei mögliche Attribute: select und disable-output-escaping. Das select-Attribut ist notwendig, da es zur Erzeugung des Ersetzungsinhalts benutzt wird. Das select-Attribut nimmt einen XPath-Ausdruck an. Mit dem XML-Code <a><b><c id="c">content</c></b></a> produziert der folgende Ausdruck das Wort »content«.
<xsl:value-of select="/a/b/c"/>
Um ein Attribut eines Elements zu bekommen, benutzen Sie das @-Symbol in Ihrem select-Attribut:
<xsl:value-of select="/a/b/c/@id"/>
Das Attribut disable-output-escaping veranlaßt den XSLT-Prozessor, die Codierung von Zeichen zu unterlassen, die mit Auszeichnungen verwechselt werden könnten. Das kann von Nutzen sein, wenn Sie eine Textausgabe erzeugen. Betrachten Sie z. B. das Dokument:
<doc>A & B</doc>
und diese Vorlage:
<xsl:template match="doc">
<xsl:value-of select="text( )" disable-output-escaping="yes"/>
</xsl:template>
Wenn disable-output-escaping seinen voreingestellten Wert no hätte, würde das Ergebnis der Vorlage als A & B dargestellt, aber wenn das Attribut auf yes gesetzt ist, lautet die Darstellung A & B. Das braucht man jedoch nicht, wenn die Ausgabeart mit dem xsl:output-Element auf Text gesetzt ist.
Wir haben das Element xsl:value-of bereits in früheren Beispielen in diesem Abschnitt benutzt, da es in XSLT von zentraler Bedeutung ist.
Iterieren über Elemente
Das Element xsl:for-each ermöglicht es Ihnen, bei einer Übereinstimmung mit einer Vorlage durch gewisse Elementtypen zu iterieren. Es hat ein notwendiges select-Attribut, das den zu iterierenden Knoten definiert. Das select-Attribut kann alles enthalten, was in einer Ansammlung von Elementen oder Knoten resultiert, und kann z. B. ein einfacher Elementname oder eine Art Pfadausdruck sein.
Das xsl:for-each-Element ist dann hilfreich, wenn Sie mit gemischtem Inhalt arbeiten und nur eine Teilmenge von Elementen im Dokument transformieren möchten. Das folgende XML-Einkaufsdokument beschreibt z. B. mehrere Arten von Einkäufen:
Wenn Sie nur an den Produkten, aber nicht an den Dienstleistungen interessiert sind, könnten Sie das for-each-Element dazu benutzen, nur die product-Elemente auszuwählen:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="/">
<html><body><xsl:apply-templates/></body></html>
</xsl:template>
<xsl:template match="purchases">
<xsl:for-each select="product">
<p>Produkt: <xsl:value-of select="./@name"/> Preis: <xsl:value-of select="./@price"/></p>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Dieses Stylesheet generiert HTML, das Detailinformationen zu Produkten, aber nicht zu Dienstleistungen enthält.
XSLT ist eine substantielle Programmiersprache und geht weit über den Rahmen dieses Buches hinaus. Zusätzlich zu den hier behandelten Elementen, mit denen Sie in XML-Quellen auswählen, suchen und iterieren können, bietet XSLT alle möglichen Standardeigenschaften einer Sprache wie z. B. Kontrollstrukturen, Bedingungen, Variablen und Funktionen. Es sind einige Ressourcen verfügbar, aus denen Sie mehr über XSLT lernen können. Wenn Sie XSLT in Ihren Projekten einsetzen möchten, ist eine gute Einführung dazu ihre Zeit auf jeden Fall wert.
<< zurück | vor >> |
Tipp der data2type-Redaktion: Zum Thema Python & XML bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an: |
Copyright © 2002 O'Reilly Verlag GmbH & Co. KG
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "Python & XML" denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.
O’Reilly Verlag GmbH & Co. KG, Balthasarstraße 81, 50670 Köln, kommentar(at)oreilly.de