This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
http://www.entwickler-press.de/ http://www.software-support.biz/ Ihr Kontakt zum Verlag und Lektorat: [email protected] Bibliografische Information Der Deutschen Bibliothek Die Deutsche Bibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.ddb.de abrufbar.
Korrektorat: Petra Kienle Satz: text & form GbR, Carsten Kienle Umschlaggestaltung: Caroline Butz Belichtung, Druck und Bindung: M.P. Media-Print Informationstechnologie GmbH, Paderborn. Alle Rechte, auch für Übersetzungen, sind vorbehalten. Reproduktion jeglicher Art (Fotokopie, Nachdruck, Mikrofilm, Erfassung auf elektronischen Datenträgern oder andere Verfahren) nur mit schriftlicher Genehmigung des Verlags. Jegliche Haftung für die Richtigkeit des gesamten Werks kann, trotz sorgfältiger Prüfung durch Autor und Verlag, nicht übernommen werden. Die im Buch genannten Produkte, Warenzeichen und Firmennamen sind in der Regel durch deren Inhaber geschützt.
Inhaltsverzeichnis Vorwort
7
Kapitel 1: Die Idee hinter XSLT 1.1 Was Sie brauchen So funktioniert XSLT Die verschiedenen XSLT-Versionen XSLT-Prozessoren CSS und seine Grenzen 1.2 Der Schnelleinstieg: Hallo, XSLT!
9 11 12 14 15 19 21
Kapitel 2: Ohne XPath geht es nicht 2.1 Mit Knoten arbeiten Achsen 2.2 Adressierung Absolute und relative Pfade 2.3 Operatoren einsetzen Variablen Funktionen gekonnt einsetzen
Kopieren Kopieren von Teilbäumen Sortieren, Gruppieren und Nummerieren Daten sortieren Elemente gruppieren Nummerierungen Variablen und Parameter Leerräume richtig behandeln Elemente und Attribute erzeugen Elemente erzeugen Attribute erzeugen Statische Texte ausgeben Text vom Parser generieren lassen Die Ausgabe steuern HTML-Ausgabe Formatierte Texte ausgeben Links und Grafiken ausgeben
Vorwort Längst hat XML den Durchbruch geschafft. Egal, ob Datenbanken, Online-Shops, Multimedia oder Wissenschaft, oft läuft im Hintergrund XML. Aber obwohl XML so oft und vielfältig eingesetzt wird, kommen die meisten Anwender nie und viele Entwickler kaum mit dieser Sprache direkt in Berührung. Dank XML können Layout und Inhalt von Dokumenten voneinander getrennt werden. Dabei ist die inhaltsorientierte Auszeichnung für die automatisierte Weiterverarbeitung gedacht. Und genau hier setzt dieses Buch an. Mit XSLT können Struktur und Inhalte von XML-Dokumenten beliebig angepasst werden. Im einfachsten Fall gibt man ein Dokument, das im XML-Format vorliegt, in einem anderen XML-Format aus. Ebenso kann aus einem reinen XML-Dokument aber auch eine HTML-Webseite werden, die dann ganz normal im Browser betrachtet werden kann. Das Wichtigste rund um das Thema XSLT erfahren Sie in diesem Buch, das sich in vier Kapitel gliedert. 쐌 Kapitel 1 liefert eine Einführung in XSLT. Sie erfahren, was es mit Parsern und Prozessoren auf sich hat, und formatieren XML-Dokumente so, dass sie im Browser ein wahrer, nun ja, Augenschmaus sind. 쐌 Kapitel 2 führt Sie in XPath ein, einer Sprache, mit der auf die einzelnen Elemente von XML-Dokumenten zugegriffen wird. 쐌 Kapitel 3 zeigt die Arbeit mit Templates. Sie erfahren, wie Sie Templates anlegen und importieren. 쐌 Kapitel 4 widmet sich ganz der Programmierung. Ja, Sie haben richtig gelesen. Denn anders als zum Beispiel bei CSS, können
schnell + kompakt
7
Vorwort
Sie in XSLT Schleifen verwenden, Variablen und Parameter einsetzen und Elemente automatisch nummerieren. Dieses Buch aus der Reihe „schnell und kompakt“ unterstützt Sie beim Erlernen von XSLT. Darüber hinaus soll Ihnen das Buch aber auch bei der täglichen Arbeit ein ständiger Begleiter sein. Haben Sie zum Beispiel einmal eine bestimmte XPath- oder XSLT-Funktion nicht parat, hilft das Buch weiter. Sollten Sie während oder nach dem Lesen des Buchs Fragen oder Anmerkungen haben, Kontakt zum Autor aufnehmen oder Kritik bzw. Lob loswerden wollen, können Sie das gerne über [email protected] tun – Ihre Nachricht ist herzlich willkommen. Hamburg, Mai 2007 Daniel Koch
8
KAPITEL 1 Die Idee hinter XSLT 1.1
Was Sie brauchen
11
1.2
Der Schnelleinstieg: Hallo, XSLT!
21
XML ist das ideale Format für die Datenspeicherung. Für die Darstellung gibt es allerdings spezielle XML-Standards wie XHTML. Um XML-Dokumente in ein solches Format übertragen zu können, wurde XSL (eXtensible Stylesheet Language) entwickelt. XSL besteht aus zwei Komponenten: 쐌 XSL-FO dient der Druckausgabe und wird in der Praxis hauptsächlich dafür verwendet, aus XML-Dokumenten PDF-Dateien zu generieren. Diese Technologie wird in diesem Buch nicht behandelt. Weitere Hinweise finden Sie aber in dem Band „XSL-FO Praxis“ von Manfred Krüger und Ursula Welsch in der gleichen Buchreihe. 쐌 XSLT wird dazu verwendet, XML-Dokumente in andere XMLDokumente oder in XML-Formate wie zum Beispiel XHTML zu transformieren. Diesem Sprachteil widmet sich dieses Buch. Bei XSLT handelt es sich um eine sogenannte turing-vollständige Programmiersprache zur Transformation von XML-Dokumenten. Dabei ist XSLT so allgemein anwendbar, dass sich aus einem hierarchisch strukturierten Ausgangsdokument Ausgaben in fast jedem beliebigen Format generieren lassen. Derzeit wird als Präsentationssprache für XML-Dokumente meistens HTML
schnell + kompakt
9
1 – Die Idee hinter XSLT
bzw. XHTML verwendet, weswegen hier auch eines der Haupteinsatzgebiete von XSLT liegt. Ebenso können aber auch SVG oder SMIL die Zielsprachen sein. Ganz allgemein werden zwei Hauptanwendungsgebiete unterschieden: 쐌 POP (Presentation Oriented Publishing) – Hier wird die Transformation zum Zweck der Darstellung durchgeführt. Mögliche Zielsprachen sind XHTML, SMIL, SVG oder DocBook. 쐌 MOM (Message Oriented Middleware) – Bei dieser Variante findet die Transformation zum Zweck des Datenaustauschs statt. Dabei dient XSLT als Übersetzer von einer XML-basierten Sprache in die andere. Ihre Wurzeln hat XSLT in der Document Style Semantics and Specification Language (DSSSL), einer Transformations- und Formatierungssprache für SGML-Dokumente. XSLT besitzt die folgenden Merkmale: 쐌 Es werden Baumstrukturen als Modelle von XML-Dokumenten verwendet. 쐌 XSLT-Stylesheets definieren die Umwandlung der EingabeBaumstruktur in eine Ausgabe-Baumstruktur. 쐌 Für den Zugriff auf Teile des Eingabebaums werden XPathAusdrücke verwendet. (Das ist übrigens einer der Gründe, warum dieses Buch nicht ohne einen Exkurs in die Welt von XPath auskommen kann.) 쐌 Mittels Vorlagen (Templates) wird die Baumstruktur des Ausgabedokuments festgelegt. In diesen Templates sind Regeln definiert, die festlegen, auf welche Weise der Ausgabebaum generiert werden soll. Derzeit wird XSLT am häufigsten dazu verwendet, aus einfachen XML-Dokumenten mittels Transformation XHTML-Dokumente inklusive CSS-Auszeichnungen zu generieren, die dann im
10
Was Sie brauchen
WWW-Browser angezeigt werden können. So lassen sich XMLDokumente auch in solchen Browsern darstellen, die XML überhaupt nicht interpretieren können. Zu Recht wird übrigens an vielen Stellen darauf hingewiesen, dass man XML-Dokumente ganz bequem per CSS formatieren kann und somit auf die Transformation mittels XSLT verzichten kann. Allerdings stößt man dort spätestens dann an die Grenzen, wenn der vom Endanwender eingesetzte Browser nicht XML-fähig ist. Ausführliche Informationen zur Kombination aus XML und CSS erhalten Sie ab Seite 19.
1.1 Was Sie brauchen XSLT lässt sich, wie so vieles im XML-Umfeld, nicht losgelöst betrachten. Denn mit XSLT allein kann man recht wenig anfangen. XSLT dient dazu, XML-Datenstrukturen zu transformieren, also in ein anderes Format zu bringen. Hilfreich ist es, wenn Sie in den folgenden Bereichen mindestens Grundkenntnisse besitzen: 쐌 XML 쐌 DTD 쐌 HTML Programmierkenntnisse im engeren Sinne benötigen Sie nicht. Allerdings gibt es in XSLT durchaus Elemente, die so auch in „echten“ Programmiersprachen verfügbar sind. Dazu gehören unter anderem Schleifen und Fallunterscheidungen. Wie Sie Ihre Stylesheets anlegen, bleibt letztendlich natürlich Ihnen überlassen. Die Beispiele in diesem Buch wurden ausschließlich mit dem Texteditor UltraEdit (http://www.ultraedit.com/) erstellt. Bei komplexeren Projekten könnte aber auch der Einsatz eines speziellen XSLT-Editors interessant sein. Auf Unix-Umge-
schnell + kompakt
11
1 – Die Idee hinter XSLT
bungen wird meistens Emacs verwendet. Für Windows gibt es die kommerziellen Produkte XML-Spy von Altova (http:// www.altova.com/) und XMetal von Softquad (http://www.softquad.com/).
So funktioniert XSLT Das Kernkonzept hinter XSLT ist die Transformation. Der Hauptunterschied zwischen XSLT und anderen Varianten der Transformation von XML-Dokumenten ist, dass XSLT die Umformung von Dokumenten als Umformung ihrer Struktur definiert. Das Kernkonzept bildet ein Datenmodell, in dem XML-Dokumente als Baum dargestellt werden. Vergleichbar ist das mit dem Document Object Model (DOM). Das zugrunde liegende Datenmodell wird dabei in Xpath beschrieben. Jedes Element bildet einen Knoten, von dem wiederum Unterelemente abzweigen (können). Bei diesen Knoten handelt es sich zum Beispiel um Elementknoten, Attributknoten und Textknoten. Es gibt drei verschiedene Arten der Transformation: 쐌 XML-Dateien werden bereits auf dem Server umgewandelt und als HTML gespeichert, bevor sie an den Client ausgeliefert werden. Sinnvoll ist diese Variante zum Beispiel, wenn die Daten aus einer XML-Datenbank einmalig in HTML konvertiert und dann online gestellt werden sollen. 쐌 Die XML-Daten und die XSLT-Stylesheets bleiben auf dem Server und werden dort transformiert. Das ist die beste Variante. Denn so kann man nicht nur alle Möglichkeiten, die XSLT zu bieten hat, ausschöpfen, es wird auch sichergestellt, dass die Seite in jedem Browser gleich aussieht. (Hier gelten natürlich trotzdem die aus HTML/CSS bekannten Unterschiede in der Darstellung im Browser.)
12
Was Sie brauchen
쐌 Eine direkte Umwandlung im Browser ist ebenfalls möglich. Dazu werden die XML- und die XSLT-Datei an den Browser übergeben. Diese Variante werden Sie bei Ihren ersten XSLTBeispielen einsetzen. In der Praxis sollten Sie darauf aber verzichten, denn bislang unterstützen längst noch nicht alle Browser diese Transformation. Das Prinzip der Transformation läuft immer gleich ab: 1. Das XML-Dokument wird vom Parser (mehr dazu im nächsten Abschnitt) eingelesen und als Baum interpretiert. 2. Das XSLT-Dokument wird vom Parser eingelesen und ebenfalls als Baum interpretiert. 3. Der XSLT-Prozessor liest beide Bäume ein. 4. Die beiden Bäume werden vom XSLT-Prozessor auf Basis der im XSLT-Dokument stehenden Anweisungen in einen neuen Baum umgewandelt. 5. Der neue Baum erhält die gewünschte serielle Form. Dafür, wie sich diese Schritte softwareseitig lösen lassen, gibt es verschiedene Möglichkeiten. So finden sich Parser und Prozessoren zum Beispiel in vielen Programmiersprachen wie PHP, Perl und Java. Darüber hinaus sind Parser und Prozessoren auch in modernen WWW-Browsern wie dem Internet Explorer und Mozilla enthalten. Ebenso kann man auch spezielle Tools kommandozeilenbasiert nutzen. Es wird zwischen zwei Transformationsarten unterschieden: 쐌 Abwärtstransformation – XML-Dokumente werden in ein Ausgabeformat umgewandelt. Das können einfache Textdateien ebenso wie XHTML- oder SVG-Dokumente sein. 쐌 Seitwärtstransformation – Das XML-Dokument wird in ein anderes XML-Format transformiert, das ebenfalls zur Datenspeicherung oder -übermittlung genutzt wird.
schnell + kompakt
13
1 – Die Idee hinter XSLT
Die verschiedenen XSLT-Versionen Entwickelt wurde XSLT ursprünglich von James Clark, der für die beiden Versionen XSLT 1.0 und 1.1 verantwortlich war. XSLT ist seit 1999 eine W3C Recommendation (http://www.w3.org/TR/ 1999/REC-xslt-19991116). Genügte die Version 1.x den damaligen Ansprüchen, hat sich das heute grundlegend geändert. Denn längst wird XSLT in Bereichen eingesetzt, die James Clark und seine Mitstreiter damals nicht in Betracht gezogen haben bzw. überhaupt nicht in Betracht ziehen konnten. Ein typisches Beispiel dafür stellen XML-Datenbanken dar, die vermehrt klassische relationale Datenbanken ablösen. Besonders wenn es in einer XML-Datenbank um die Adressierung und Filterung des Datenbestands geht, stößt man mit den herkömmlichen Sprachen schnell an die Grenzen. Um Daten zu finden, die bestimmte Eigenschaften erfüllen, wird XQuery (http://www.w3.org/XML/ Query) eingesetzt. Die so ermittelten Daten können anschließend mittels Dokumenttransformation ganz nach Wunsch aufbereitet werden. Und genau bei dieser Transformation kommt XSLT ins Spiel. Damit XSLT aber überhaupt XQuery-Datensätze verarbeiten konnte, musste das Datenmodell angepasst werden, was auch Auswirkungen auf XPath hatte. XSLT 2.0 und XQuery verwenden nun das Datenmodell von XPath 2.0. Derzeit wird noch an XSLT 2.0 gearbeitet. Dieser Sprachstandard hat mittlerweile den Status Candidate Recommendation erreicht. Eine Verabschiedung steht also unmittelbar bevor. Den aktuellen Entwurf finden Sie unter http://www.w3.org/TR/xslt20/. Auch wenn XSLT 2.0 noch nicht offiziell verabschiedet wurde, unterstützen die meisten Prozessoren diese Version. Als eines der Hauptkriterien für XSLT 2.0 hat das W3C die Kompatibilität zur Version 1.0 definiert. Die in diesem Buch wiedergegebenen Informationen stimmen somit also weitestgehend für beide Sprachversionen.
14
Was Sie brauchen
Unterschiede zwischen Parser und Prozessor Der folgende Abschnitt befasst sich mit XSLT-Prozessoren. Bevor es bei diesem Thema ins Detail geht, aber noch einige Worte zu den verwendeten Begrifflichkeiten. Sehr oft werden Parser und Prozessor vertauscht oder gleichgesetzt. Das ist zwar nicht weiter schlimm, einwandfrei ist es allerdings nicht, denn Parser kontrollieren Dokumente auf ihre syntaktische Korrektheit. XSLTProzessoren hingegen transformieren XML-Dokumente mithilfe von XSLT-Stylesheets in das gewünschte Ausgabeformat.
XSLT-Prozessoren Für die XSLT-Transformation wird ein Prozessor benötigt. Dieser Prozessor muss nicht nur XML-Dokumente verarbeiten können, sondern auch die Elemente und Funktionen von XSLT beherrschen. XSLT-Prozessoren sind Software-Module, die an verschiedensten Stellen eingesetzt werden. Soll die Transformation der XML-Datei in formatierter Form im Browser erfolgen, muss das Modul direkt im Browser selbst integriert sein. Der Internet Explorer hat einen entsprechenden Parser an Bord. Für Sie als Entwickler hat das den Vorteil, dass Sie Ihre XSLT-Anwendungen direkt im Browser testen können. Dazu öffnen Sie dort das betreffende XML-Dokument, an das das XSLT gebunden ist. Ebenso können Sie aber auch das XSLT-Dokument direkt im Browser öffnen. Das wird dann als hierarchisches Dokument angezeigt. XSLT-Parser sind aber auch oft in den Webserver integriert. So können XML-Daten nach HTML transformiert werden, bevor sie mittels HTTP an den aufrufenden Client-Browser übertragen werden. Das hat den Vorteil, dass sich moderne XML-Daten auch in noch so antiquierten Browsern anzeigen lassen.
schnell + kompakt
15
1 – Die Idee hinter XSLT
Die folgende Übersicht zeigt die beliebtesten Prozessoren: 쐌 msxml ist eine DLL-Bibliothek, die man in eigenen Programmen verwenden kann, die von Microsoft aber auch im Internet Explorer eingesetzt wird. 쐌 Saxon (http://saxon.sourceforge.net/) ist eine schnelle XSLT-Implementierung, die sich durch zahlreiche Erweiterungen auszeichnet. Zu diesem Prozessor dann im nächsten Abschnitt mehr. 쐌 FastXML (http://www.geocities.com/fastxml/) bietet eine hohe Performance, die hauptsächlich auf Code-Tuning und Optimierung zurückzuführen ist. 쐌 Sablotron (http://www.gingerall.org/sablotron.html) ist ein schnelles OpenSource-Toolkit für XML, in dem auch ein XSLTProzessor integriert ist. 쐌 Xalan ist ein OpenSource-XSLT-Prozessor der Apache Software Foundation, dessen Ziel es ist, möglichst nah an den Standards von XSLT und XPath zu sein. Xalan gibt es als C++ (http://xml.apache.org/xalan-c/index.html) und als Java-Version http://xml.apache.org/xalan-j/index.html). Welchen Prozessor man am besten einsetzen sollte, lässt sich pauschal nicht sagen. Allerdings gibt es einige Kriterien, die Sie bei der Prozessorwahl berücksichtigen sollten: 쐌 쐌 쐌 쐌 쐌
Konformität zu den Standards von XSLT und XPath Gute Performance Verfügbare Schnittstellen Verbreitung des Prozessors Erweiterbarkeit
In der Praxis wird die Transformation meistens im Zusammenspiel mit Anwendungen und Programmiertechnologien durchgeführt. Wer zum Beispiel PHP verwendet, kann die XSLT-Transformation mittels der in PHP bereitgestellten XSLT-Funktionen
16
Was Sie brauchen
(http://de.php.net/manual/de/ref.xslt.php) durchführen. PHP setzt als Parser übrigens Sablotron ein. Prozessoren im Einsatz Sie haben gesehen, dass es viele XSLT-Prozessoren auf dem Markt gibt, die sich vor allem darin unterscheiden, wie vollständig sie XSLT implementieren und wie schnell sie sind. Bei der Verwendung ähneln sich die Prozessoren allerdings. Der Einsatz von XSLT-Prozessoren wird hier am Beispiel von Saxon gezeigt. Dieser Prozessor war in älteren Versionen noch völlig kostenlos, wird mittlerweile von der Firma Saxonica Ltd. (http://www.saxonica.com/) allerdings kommerziell vertrieben. In einer abgespeckten Version ist er aber immer noch kostenlos verfügbar und kann von der Projektseite http://saxon.sourceforge.net/ heruntergeladen werden. Saxon gibt es in einer .NET- und in einer Java-Version. Hier wird die Verwendung von Saxon in einer Java-Umgebung gezeigt. Voraussetzung dafür ist eine Java-Laufzeitumgebung in Version 1.5 oder höher. Saxon wird folgendermaßen gestartet: java -jar $SAXON/saxon8.jar quelle.xml ausgabe.xsl
Als Argumente werden dem Java-Interpreter die Option –JAR und der vollständige Pfad der Datei saxon8.jar übergeben. Zusätzlich gibt man das Ausgangsdokument (quelle.xml) und das Stylesheet (ausgabe.xsl) an. XSLT im Browser Moderne Browser wie Mozilla und der Internet Explorer ab Version 5 transformieren XML-Dokumente direkt während der Laufzeit. Dazu muss innerhalb des Dokuments eine Processing
schnell + kompakt
17
1 – Die Idee hinter XSLT
Instruction stehen, die auf ein Stylesheet hinweist und auf die der Browser tatsächlich zugreifen kann.
Durch eine solche Processing Instruction werden XML-Datei und Stylesheet miteinander verknüpft. Ausführliche Informationen dazu erhalten Sie später. Fehlt die Angabe eines Stylesheet, stellen der Internet Explorer und Mozilla XML-Dokumente in einer Baumstruktur dar.
Abb. 1.1: Die Baumstruktur im Internet Explorer
Eine solche Darstellung ist zwar bei der Entwicklung der XMLStruktur hilfreich, optisch ansprechend ist sie freilich nicht. Und genau an diesem Punkt kommen Stylesheets ins Spiel. Die können aus einer Baumstruktur eine ganz normale Webseite machen.
18
Was Sie brauchen
CSS und seine Grenzen XML-Dokumente können mittels CSS formatiert und im Browser ausgegeben werden. Wie einfach das geht, zeigt folgendes Beispiel: Hallo, Welt!
Diese einfache XML-Struktur soll nun mittels CSS im Browser angezeigt werden. Dazu wird über xml-stylesheet die CSS-Datei angegeben, die die Stylesheet-Definitionen enthält. text { position:absolute; top:20px; left:40px; background-color:#c0c0c0; padding:20px; color:#FFFFFF; font-family:Arial,Helvetica,sans-serif; font-size:40px; }
In dieser Datei werden das oder die zu formatierenden XMLTags angegeben. Bei der Syntax selbst handelt es sich um ganz normales CSS. Ruft man die XML-Datei in einem geeigneten Browser (Internet Explorer ab Version 5 und Mozilla) auf, ergibt sich folgendes Bild:
schnell + kompakt
19
1 – Die Idee hinter XSLT
Abb. 1.2: So sieht es doch schon besser aus
Auf diese Weise können Sie Ihr gesammeltes CSS-Wissen, das Sie bislang vielleicht ausschließlich für die Formatierung von HTML-Seiten genutzt haben, nehmen und auf XML anwenden. Das hat den Vorteil, dass Sie auf vorhandenes Know-how zurückgreifen und sich nicht in XSL und XSLT einarbeiten müssen. Allerdings hat die Kombination XML/CSS deutliche Nachteile gegenüber XSL. 쐌 Ältere Browser können mit XML und CSS nichts anfangen und zeigen entweder gar nichts oder unformatierten Text. 쐌 In CSS gibt es kaum Möglichkeiten, Daten bei der Ausgabe zu filtern. 쐌 Klassische XSLT-Funktionen wie Sortieren und Gruppieren sind in CSS nicht verfügbar. XSLT ist nicht einfach eine alternative Möglichkeit zur Ausgabe von XML-Dateien , sondern bringt weitreichende Neuerungen mit sich.
20
Der Schnelleinstieg: Hallo, XSLT!
1.2 Der Schnelleinstieg: Hallo, XSLT! Auf zwei verschiedene Arten lässt sich XSLT auf XML-Dokumente anwenden. 쐌 Es wird in XML-Dokumente eingebunden. 쐌 Beide Dokumente werden einem XSLT-Prozessor übergeben. In der Praxis kommt man hauptsächlich mit der ersten Variante in Berührung. Zum Testen der Anwendungen empfiehlt sich allerdings das direkte Einbinden der XML-Datei. Den ersten Kontakt zur Transformation mit XSLT soll – wie es in der Entwicklerwelt gute Sitte ist – das klassische Hallo, Welt! herstellen. Im folgenden Beispiel wird davon ausgegangen, dass alle drei benötigten Dateien im gleichen Verzeichnis liegen. Zunächst die DTD:
Diese Document Type Definition wird in der externen Datei welt.dtd gespeichert. In ihr ist lediglich das Element welt definiert. Hinweis Da in diesem Buch der Fokus auf XSLT liegt, wird im weiteren Verlauf auf die Definition von DTDs verzichtet, da diese wichtigen Platz wegnehmen würden. Die XML-Datei sieht folgendermaßen aus: Hallo, Welt!
schnell + kompakt
21
1 – Die Idee hinter XSLT
Nachdem über das DOCTYPE-Element die externe DTD eingebunden wurde, wird eine Processing Instruction definiert. Hier werden der Typ (type) der einzubindenden Datei und deren Pfad und Dateiname (href) angegeben. Es handelt sich dabei um eine Anweisung für die verarbeitende Software (zum Beispiel den Browser). Von besonderem Interesse für dieses Buch ist nun freilich der Aufbau der XSL-Datei welt.xsl.
Ein Blick auf die einzelnen Bereiche der Datei soll die Syntax veranschaulichen. Da auch XSL-Dateien XML-gerechte Dateien sind, werden diese mit einer XML-Deklaration eingeleitet.
22
Der Schnelleinstieg: Hallo, XSLT!
Die gesamte XSL-Datei ist in folgendes Element eingeschlossen: …
Die Notation ist die typische Schreibweise, wenn innerhalb einer Datei mehrere Namensräume verwendet werden. Bei XSLT-Dokumenten ist auf jeden Fall der Namensraum für XSLT anzugeben. Zusätzlich können sie die Namensräume für XML Schema und XPath definieren. In diesem Fall müsste das einleitende -Element erweitert werden.
Der wichtigste Bestandteil von XSLT-Dokumenten sind Templates. In Templates wird die gesamte Ausgabe definiert. Über das match-Attribut gibt man an, welches XML-Dokument transformiert werden soll. Bei dem Attributwert handelt es sich um einen XPath-Ausdruck. Durch match="/" wird das Wurzelelement beschrieben. Es handelt sich also um das zentrale Template. …
schnell + kompakt
23
1 – Die Idee hinter XSLT
Um innerhalb eines Stylesheet auf Werte zuzugreifen, wird das select-Attribut des Elements verwendet.
Diese Syntax wählt den Knoten aus, dessen Inhalt angezeigt werden soll. Wenn Sie die XML-Datei in einem geeigneten Browser aufrufen, sehen Sie, dass das Stylesheet greift und die XMLStruktur formatiert ausgegeben wird.
Abb. 1.3: Der gewünschte Knoten wird ausgegeben
Auf diese Weise können Sie die Beispiele aus diesem Buch nachvollziehen und sehen immer sofort, ob sich in Ihre XSLT-Datei der Fehlerteufel eingeschlichen hat. Denn erkennt der Parser einen Syntaxfehler, macht er Sie augenblicklich darauf aufmerksam. Der Internet Explorer meldet sich zum Beispiel folgendermaßen:
24
Der Schnelleinstieg: Hallo, XSLT!
Abb. 1.4: Der Internet Explorer hat einen Syntaxfehler entdeckt.
So sehen Sie in aller Regel recht gut, wo der Fehler steckt, und können ihn problemlos beseitigen. Im aktuellen Beispiel moniert der Parser, dass das Anfangstag nicht mit dem Endtag übereinstimmt.
schnell + kompakt
25
KAPITEL 2 Ohne XPath geht es nicht 2.1
Mit Knoten arbeiten
28
2.2
Adressierung
34
2.3
Operatoren einsetzen
42
Ein XSLT-Buch zu schreiben, ohne auf XPath einzugehen, ist praktisch unmöglich. XPath ist eine Sprache, mit der auf die Elemente von XML-Dokumenten zugegriffen werden kann. Wie eng die XML Path Language (http://www.w3.org/TR/xpath) mit XSLT verbunden ist, macht ein Faktor besonders deutlich: Beide Standards wurden zum gleichen Zeitpunkt vom W3C verabschiedet. Haupteinsatzzweck von XPath ist die Adressierung von Elementen in XSLT-Dokumenten. Im Zusammenhang mit XSLT hat XPath die folgenden Aufgaben: 쐌 Adressierung von Daten 쐌 Definition logischer Ausdrücke 쐌 Zusätzliche Funktionen bereitstellen Darüber hinaus wird XPath auch in anderen Standards wie zum Beispiel der XML-Abfragesprache XQuery eingesetzt. Das Kernkonzept bilden die sogenannten Pfadausdrücke. Durch die können Knoten anhand ihrer Eigenschaften und der Eigenschaften benachbarter Knoten beschrieben werden.
schnell + kompakt
27
2 – Ohne XPath geht es nicht
Hinweis XPath ist übrigens nicht nur ein wichtiger Bestandteil von XSLT, sondern wird auch in anderen Bereichen wie zum Beispiel XPointer eingesetzt.
2.1 Mit Knoten arbeiten Wie XSLT und XML sieht auch XPath die einzelnen Elemente (Attribute, Elemente, Kommentare usw.) von Dokumenten als Knoten an. Innerhalb von XPath gibt es sieben verschiedene Knotentypen. Die Knotentypen selbst sind nicht unmittelbarer Bestandteil der Adressierungssyntax von XPath, allerdings ist es hilfreich, die Begriffe zu kennen. 쐌 Root-Knoten (root node) – die Wurzel des XML-Dokuments. Der Wurzelknoten ist selbst kein Element, sondern lediglich die abstrakte Ursprungswurzel der Baumstruktur des Dokuments. 쐌 Elementknoten (elements node) – jedes Element stellt aus Sicht von XPath einen Elementknoten dar. Um den Zugriff auf ein Element zu erleichtern, kann es mit einer ID eindeutig beschrieben werden. Der erweiterte Name eines Elementknotens ist der Elementname selbst. Der Textwert ist der Textwert des Elements und seiner Kinder. 쐌 Attributknoten (attribute node) – jedes Attribut, das zu einem Element gehört, ist ein Attributknoten. Anders als beim DOM ist ein Attributknoten hier aber kein Kind des Elements. Attribute können dementsprechend auch nicht als Kinder eines Elements angesprochen werden. Der erweiterte Name des Knotens ist der Attributname mit eventuell vorhandenem Präfix. Der Textwert des Knotens ist der Attributwert. 쐌 Kommentarknoten (comment node) – jeder Kommentar ist ein Kommentarknoten. Kommentarknoten besitzen keinen erwei-
28
Mit Knoten arbeiten
terten Namen. Alles, was zwischen steht, ist der Textwert des Knotens. 쐌 Namensraumknoten (namespace node) – Elemente und Attribute können Angaben zum Namensraum enthalten, wenn entsprechende Namensräume in die XML-Datei importiert werden. Namensraumknoten sind alle Attributknoten mit dem Namen xmlns oder dem Präfix xmlns. Ebenso sind alle Knoten Namensraumknoten, wenn ein Vorfahrenelement das Präfix xmlns besitzt. (Dieses darf vorher allerdings nicht aufgehoben worden sein.) Der erweiterte Name eines Namensraumknotens ist der lokale Name des Namensraums. Der Textwert ist der entsprechende URI, mit dem der Namensraum verbunden wurde. 쐌 Processing-Instruction-Knoten (processing instruction node) – Verarbeitungsanweisungen stehen außerhalb des eigentlichen Dokumentbaums. Verarbeitungsanweisungen beginnen mit . Aus Sicht von XPath sind sie ein eigener Knotentyp. Die XML-Deklaration zu Beginn von XML-Elementen ist in diesem Sinn allerdings keine Verarbeitungsanweisung. 쐌 Textknoten – sämtlicher Inhalt des Dokuments, der nicht zu einem der zuvor genannten Knoten gehört, ist ein Textknoten. Neben dem reinen Text gehören auch CDATA-Abschnitte zu den Textknoten. Diese werden in normalen Text umgewandelt und nicht etwa als Elementknoten betrachtet. Textknoten besitzen keinen erweiterten Namen. Am besten lassen sich die XPath-Elemente anhand eines einfachen Beispiels vorstellen. Als Ausgangsbasis dient folgende XML-Datei:
schnell + kompakt
29
2 – Ohne XPath geht es nicht
Nick Hornby Bret Easton Ellis
Zur Ausgabe wird ein ebenso einfaches XSLT-Stylesheet verwendet.
In diesem Stylesheet wird nur das Template für die Autoren aufgerufen. Über werden die XPath-Aufrufe variiert. Der im aktuellen Beispiel verwendete Punkt steht für den aktuellen Knoten, hier also für die gesamte XML-Struktur des -Elements. Wollen Sie nun nicht auf den ersten, sondern einen untergeordneten Knoten zugreifen, verwenden Sie dessen Knotennamen.
30
Mit Knoten arbeiten
Ebenso ist auch der Zugriff auf Unterknoten möglich. Angenommen, unterhalb von würde sich das Element befinden. Dann sähe die Syntax folgendermaßen aus: vorname/zweitervorname
Sämtliche Knoten eines Elements stehen in einer bestimmten Beziehung zueinander. XPath verwendet für die Darstellung dieser Beziehung Verwandtschaftsgrade. 쐌 Ein übergeordneter Knoten ist der Elternknoten (parent). Bis auf das Wurzelement besitzt jedes Element einen Elternknoten. 쐌 Vorfahren sind die Elternknoten, Elternknoten von Elterknoten und so weiter (ancestors). 쐌 Untergeordnete Knoten sind Kindknoten (child). 쐌 Untergeordnete Kindknoten sind Kindknoten (decendants). 쐌 Geschwisterknoten sind Knoten, die den gleichen Elternknoten haben (siblings). Über spezielle XPath-Ausdrücke kann auf einzelne Knoten zugegriffen werden. Hier sind Adressierung und Achsen entscheidend.
Achsen Ein weiteres Kernkonzept neben der Adressierung (die im nächsten Abschnitt vorgestellt wird) von Knoten sind Achsen. Die Achse legt fest, in welche Richtung Elemente ausgewählt werden. Wobei mit Richtung hier die Richtung im Knotenbaum gemeint ist. Es gibt Knoten, die von anderen Knoten abhängig sind, und solche, die auf der gleichen Ebene liegen. Es gibt in XPath
schnell + kompakt
31
2 – Ohne XPath geht es nicht
verschiedene Begriffe wie Eltern und Kind, die als Achsen (axes) bezeichnet werden. Zunächst eine ganz typische Syntax, die sich wieder auf das bekannte Autoren-Beispiel bezieht:
Diese Syntax liefert alle Kindknoten mit dem Elementnamen vorname. Die folgende Tabelle gibt einen Überblick über die in XPath verfügbaren Achsen. In der Tabelle wird auf folgendes Beispiel zurückgegriffen:
Und hier die verfügbaren Achsen: Tabelle 2.1: Die verfügbaren Achsen
Achse
Beschreibung
Attribut (attribute)
Attribute haben eine Sonderstellung und werden nicht in das Schema child, parent, descendant und ancestor eingefügt. Bei einer angenommenen Struktur von ist b das Attribut von .
32
Mit Knoten arbeiten Tabelle 2.1: Die verfügbaren Achsen (Forts.)
Achse
Beschreibung
Kind (child)
Element ist aus Sicht von ein Kindelement.
Elternknoten (parent)
Element ist aus Sicht von der Elternknoten.
Nachkommen (descendant)
Die Elemente und sind aus Sicht von Nachkommen.
Vorfahr (ancestor)
Aus Sicht von sind die Elemente und Vorfahren.
Nachfolgende Knoten (following)
Aus Sicht des ersten -Elements sind das zweite - und das zweite -Element nachfolgende Knoten.
Vorherige Geschwisterknoten (preceding-sibling)
Aus Sicht des dritten -Elements ist das zweite -Element ein Geschwisterknoten, nicht aber das erste -Element.
Aus Sicht des ersten - ist das zweite -Element ein nachfolgender Geschwisterknoten, nicht aber das dritte -Element.
Namensraum (namespace)
Bei
dem
angenommenen
Element
ist name aus Sicht von a der
Namensraum. Der aktuelle Knoten (self)
Wird das Element gerade vom XSLT-Prozessor bearbeitet, hat es in diesem Moment den Status self.
Nachkomme oder der aktuelle Knoten (descendant-or-self)
Wird das Element gerade vom XSLT-Prozessor bearbeitet, dann haben und das nachfolgende den Status descendant-or-self.
schnell + kompakt
33
2 – Ohne XPath geht es nicht Tabelle 2.1: Die verfügbaren Achsen (Forts.)
Achse
Beschreibung
Vorfahre oder der aktuelle Knoten (ancestor-or-self)
Wird das Element gerade vom XSLT-Prozessor bearbeitet, dann haben und das vorhergehende den Status descendant-or-self.
Hinweis Beachten Sie, dass nach dem Achsennamen zwei Doppelpunkte notiert werden müssen. Nur so kann der Parser zwischen einem Elementnamen und dem Achsennamen unterscheiden.
2.2 Adressierung Um auf Knoten zeigen zu können, wird vom aktuellen Knoten ausgehend ein bestimmter Pfad definiert. Dem folgt der Interpreter, um zum entsprechenden Knoten oder der entsprechenden Knotenmenge zu kommen. In XPath wird zwischen ausführlicher und verkürzter Notation unterschieden. Bei der ausführlichen Variante werden die vollständigen Achsenbezeichnungen verwendet. /child::autor/child::buch/attribute::titel
Sie können aber auch allen Ballast weglassen und sich ausschließlich auf die Elemente konzentrieren. Das verkürzte Gegenstück für das gezeigte Beispiel sieht folgendermaßen aus: /autor/buch/@titel
34
Adressierung
Für welche dieser beiden Varianten Sie sich letztendlich entscheiden, ist Geschmackssache. Effizienter ist aber natürlich die verkürzte Notation. Gerade wenn Sie am Anfang Ihrer XPath-Karriere stehen, kann Ihnen die ausführliche Notation aber helfen, den Überblick zu behalten.
Absolute und relative Pfade Neben der ausführlichen und der verkürzten Notation gibt es auch zwei verschiedene Varianten, wenn es darum geht, Pfade zu bestimmen. XPath kennt absolute und relative Pfade. Bei einem relativen Pfad wird von dem Knoten ausgegangen, an dem sich der Interpreter aktuell befindet. Befindet sich der Interpreter also gerade innerhalb des Elementbaums, geht der relative Pfad vom aktuellen Knoten aus und zeigt auf einen anderen Knoten innerhalb des Baums. Folgendes Beispiel dient als Ausgangspunkt für weitere Erklärungen: Nick Hornby Bret Easton Ellis
schnell + kompakt
35
2 – Ohne XPath geht es nicht
Zunächst geht es um die Adressierung der Dokumentwurzel.
Das Wurzelelement wird über einen Schrägstrich adressiert. Im aktuellen Beispiel wird über ein Template für die XML-Dokumentwurzel definiert. Innerhalb des match-Attributs wird die Dokumentwurzel bestimmt. Relative Pfadangaben Es handelt sich hier um eine verschachtelte Elementstruktur. Befindet sich der Interpreter bereits bei dem Knoten und will man von dort auf den -Knoten zugreifen, verwendet man die folgende Syntax:
Um das Kindelement aus Sicht des Großvaterelements zu adressieren, muss im match-Attribut des -Elements der entsprechende Pfad angegeben werden. Die verkürzte Syntax dafür lautet autoren/autor. In der ausführlichen Notation ergibt sich folgendes Bild: child::autoren/child::autor
Am einfachsten versteht man das Prinzip der relativen Pfadangaben, wenn man sich bewusst macht, dass man nur den hierarchie-bestimmenden Knotennamen folgen muss.
36
Adressierung
Absolute Pfadangaben Absolute Pfadangaben werden mit einem Schrägstrich eingeleitet, der die Dokumentwurzel repräsentiert. Alle weiteren Hierarchieebenen kennzeichnen Sie durch weitere Schrägstriche. Bei der ausführlichen Syntax werden die Knoten, über die der Pfad läuft, anhand ihrer Achsen und den entsprechenden Knotennamen beschrieben und durch zwei Doppelpunkte voneinander getrennt.
Verwendet wird meistens die verkürzte Notation ohne Achsenbezeichnungen. Im gezeigten Beispiel wird über die -Anweisung ein Template für das Element definiert, bei dem es sich um ein Kindelement von handelt. wiederum ist ein Kindelement der Dokumentwurzel. Adressierung von Attributen Die Attribute von Elementen werden in XPath als Attributknoten behandelt und als eben solche adressiert. Name:
In diesem Beispiel wird davon ausgegangen, dass die XML-Notation existiert.
schnell + kompakt
37
2 – Ohne XPath geht es nicht
Wildcards verwenden Wollen Sie mehrere Knoten auf einmal auswählen, können Sie Wildcards verwenden.
Das gezeigte Beispiel bewirkt, dass alle Kindelemente von auf einen Schlag ausgegeben werden. Dazu wird innerhalb der Template-Definition von dem selectAttribut von das Wildcard- bzw. Sternzeichen zugewiesen. Wollen Sie die ausführliche Notation verwenden, müssten Sie die Achsenbezeichnung child:: angeben. Beachten Sie, dass durch das Wildcard-Zeichen ausschließlich die nächstuntere Hierarchieebene ausgewählt wird. Wollen Sie auf alle untergeordneten Hierarchieebenen zugreifen, unabhängig von der tatsächlichen Verzweigtiefe des Baums, müssen Sie // verwenden. Positionsangaben und Bedingungen Mit absoluten und relativen Pfadangaben lässt sich nicht jedes Element ansprechen. Ein typisches Beispiel dafür könnte folgendermaßen aussehen: ... ... ...
Über die Adressierung bibliothek/autor würden Sie hier lediglich auf das erste -Element zugreifen. Um dieses Problem zu umgehen, könnten Sie zwar auf eine -Schleife
38
Adressierung
zurückgreifen, aber auch das hilft nicht in jedem Fall. XPath hält für solche Zwecke spezielle Syntaxvarianten bereit, bei denen mittels Positionsangaben und Bedingungen ganz gezielt auf einzelne Elemente zugegriffen werden kann. In den folgenden Beispielen kommen einige XPath-Funktionen zum Einsatz. Ausführliche Informationen dazu finden Sie im weiteren Verlauf dieses Buchs. Hier einige Beispiele: self::bibliothek
Dadurch wird das aktuelle Element adressiert – allerdings nur unter der Einschränkung, dass es vom Typ ist. autor[last()]
Durch diese Syntax wird das letzte Kindelement vom Typ adressiert. Verwendet wird dafür die XPath-Funktion last(). autor[last()-1]
Um das vorletzte Element vom Typ zu adressieren, wird diese Syntax verwendet. Auch hier kommt die last()-Funktion zum Einsatz. bibliothek//autor
Diese Syntax adressiert alle Elemente vom Typ , die sich aus Sicht des aktuellen Knotens unterhalb von Elementen des Typs befinden. /bibliothek/autor[3]/buch[2]/seite[5]
schnell + kompakt
39
2 – Ohne XPath geht es nicht
Hier wird vom dritten Autor aus dem zweiten Buch die fünfte Seite adressiert. Im letzten Beispiel wird das Kindelement adressiert. Das geschieht allerdings nur dann, wenn das Attribut land den Wert eng besitzt. autor[@land=''eng]
Zusammengefasst werden die gezeigten Varianten unter dem Oberbegriff Prädikat. Die Knotensuche mit Knotentests verfeinern Anhand von Knotentests können Sie die Suche nach dem betreffenden Knoten bzw. der Knotenmenge noch exakter beschreiben. Es handelt sich bei Knotentests um zusätzliche Möglichkeiten zu den zuvor beschriebenen Achsendefinitionen. Die folgenden Werte können als Knotentests verwendet werden: 쐌 Knotenname – innerhalb der Knotenmenge wird nach dem Knoten gesucht, dessen erweiterter Name hier angegeben wurde. 쐌 * – alle Knoten innerhalb der Knotenmenge der Achsendefinition sollen gefunden werden. Der Name spielt dabei keine Rolle. 쐌 Präfix:* oder Präfix:Name – wird ein Präfix angegeben, wird nach allen Knoten aus dem Namensraum gesucht, die dem Namen entsprechen. Ebenso kann auch ein Stern angegeben werden. In diesem Fall werden dann alle Knoten des Namensraums gefunden, unabhängig von ihrem Namen. 쐌 comment() – wählt alle Kommentarknoten aus. 쐌 text() – wählt alle Textknoten aus. 쐌 node() – wählt Knoten eines beliebigen Typs aus. 쐌 processing-instruction()– wählt den Knoten aus, der die Verarbeitungsanweisung enthält.
40
Adressierung
Wie einfach sich Knotentests einsetzen lassen, zeigt folgendes Beispiel: child::*
Hierdurch werden alle Kindknoten ausgewählt. Verkürzte Syntax für den Knotenzugriff Um sich die Tipparbeit etwas zu erleichtern, hält XPath einige verkürzte Syntaxformen bereit. child::weglassen
Um auf die Kindelemente des aktuellen Knotens zuzugreifen, müssen Sie nicht jedes Mal die lange Syntax child::knoten wählen, sondern Sie lassen child:: einfach weg. Die Syntax beginnt mit dem Knotennamen. Anstelle von child::knoten wird also knoten verwendet. Auch bei der Auswahl von Attributen hilft die verkürzte Schreibweise weiter. Anstelle von attribute::name setzen Sie das @-Zeichen ein. autor[@land
Dabei steht das @ als Synonym für das Wort attribute. Elternknoten werden normalerweise über parent::node() angegeben. Diese Syntax lässt sich abkürzen, indem man zwei Punkte verwendet. ../Knoten
Diese Syntax bewirkt das Gleiche wie parent::node(), ist aber um einiges kürzer.
schnell + kompakt
41
2 – Ohne XPath geht es nicht
Interessant ist auch die abkürzende Schreibweise //, die anstelle von /descendant-or-self::node() verwendet wird. Durch diese Syntax können Sie den kompletten Teilbaum mit dem aktuellen Kontextknoten als Wurzel referenzieren. So sorgt die folgende Syntax dafür, dass innerhalb einer HTML-Datei alle -Elemente ausgewählt werden, die ein href-Attribut besitzen. //a[@href]
Überall dort, wo es möglich ist, sollten Sie die verkürzte Notation auch tatsächlich verwenden. Denn so lassen sich XSLT-Dokumente nicht nur schneller schreiben, sie sind für erfahrene Entwickler oft sogar besser zu lesen. (Einsteiger tun sich erfahrungsgemäß allerdings mit der verkürzten Syntax etwas schwer.)
2.3 Operatoren einsetzen In XPath gibt es wie in „echten“ Programmiersprachen Operatoren. Und ebenso wie dort unterscheidet man auch in XPath zwischen verschiedenen Arten von Operatoren. Bevor die Operatoren vorgestellt werden, noch ein Wort zu den Datentypen, denen entscheidende Bedeutung zukommt. Hier die wichtigsten Datentypen, die es in XPath gibt: 쐌 쐌 쐌 쐌
Zahlen Text Knoten und Knotensammlungen Boolesche Werte true (wahr) und false (falsch)
Die folgende Tabelle zeigt die verfügbaren Operatoren, unterteilt nach ihren Einsatzgebieten:
42
Operatoren einsetzen Tabelle 2.2: XPath-Operatoren in der Übersicht
Operator
Beschreibung
Arithmetische Operatoren *
Multiplikation
+
Addition
-
Subtraktion
mod
Gibt den Rest einer ganzzahligen Division zurück.
div
Führt eine Gleitkommadivision nach IEEE 754 aus.
Vergleichsoperatoren =
Vergleicht zwei Werte.
!=
Prüft zwei Werte auf Ungleichheit.
< bzw. <
Prüft, ob der erste Wert kleiner als der zweite ist.
> bzw. >
Prüft, ob der erste Wert größer als der zweite ist.
= bzw. >=
Prüft, ob der erste Wert größer oder gleich dem zweiten ist.
Logische Operatoren and
Zwei Ausdrücke werden mit UND (beide Ausdrücke) verknüpft.
or
Zwei Ausdrücke werden mit ODER (einer von beiden Ausdrücken) verknüpft.
Sonstige ()
schnell + kompakt
Klammern kennzeichnen einen logischen Zusammenhang. Sie werden oft in mathematischen Berechnungen oder bei logischen Verknüpfungen eingesetzt.
43
2 – Ohne XPath geht es nicht Tabelle 2.2: XPath-Operatoren in der Übersicht
Operator
Beschreibung
|
Zwei Knoten oder Knotenmengen werden zu einer Knotenmenge verbunden.
/
Verbindet einen Ausdruck zu einem relativen Pfad.
Der Einsatz der Operatoren ist denkbar einfach und wird Ihnen auch in diesem Buch noch an mehreren Stellen begegnen. Einen ersten Eindruck vermittelt folgendes Beispiel, in dem die beiden logischen Operatoren and und or eingesetzt werden: autor[(buch or zeitschrift) and publiziert]
Die Angabe bezieht sich auf alle -Elemente mit mindestens einem - oder -Element und mindestens einem -Element. Je nach Parser müssen die beiden Operatoren < und > mit ihren Entitäten angeben werden. Anstelle von < notieren Sie < und anstelle von > schreiben Sie >.
Variablen In XPath selbst können keine Variablen definiert werden. Allerdings lassen sich die in XSLT definierten Variablen verwenden. (Mehr zu XSLT-Variablen erfahren Sie ab Seite 95.) Auf den Wert einer Variable können Sie zugreifen, indem Sie vor den Variablennamen ein Dollarzeichen setzen. Angenommen, in XSLT wurde folgende Variable definiert: Nick Hornby
44
Operatoren einsetzen
Über $aname können Sie nun auf den Wert dieser Variable zugreifen und erhalten den Wert Nick Hornby.
Funktionen gekonnt einsetzen Über die XPath-Funktionen lässt sich die Transformation der XML-Ausgangsdaten in den Ergebnisbaum steuern. Zudem stellen sie zusätzliche Features zur Verfügung. Gedacht sind die Funktionen für den Einsatz in XSLT-Stylesheets. Die Syntax ist immer identisch. Hinter dem Funktionsnamen folgen zwei Klammern, in denen sogenannte Argumente stehen können. Bevor die einzelnen Funktionen vorgestellt werden, ein Beispiel für die Verwendung von XPath-Funktionen:
Name des Knotens:
local-name:
Inhalt:
schnell + kompakt
45
2 – Ohne XPath geht es nicht
In dieser Syntax kommen die beiden Funktionen name() und local-name() zum Einsatz. Während über name() der Name eines Knotensets ermittelt wird, liest local-name() den lokalen Namen eines Knotensets aus. Viele Funktionen erwarten Argumente. In den folgenden Tabellen sind diese innerhalb der Klammern hinter den Funktionsnamen aufgeführt. So bedeutet die Angabe count(Knotenmenge), dass die Funktion count() als Argument eine Knotenmenge erwartet, was in der Praxis dann zum Beispiel so aussehen könnte: count(//autor)
Da die Funktionen einen Wert zurückliefern, werden sie innerhalb von XSLT hauptsächlich dort verwendet, wo Attributen Werte zugewiesen werden. So könnte zum Beispiel das XSLTElement folgendermaßen notiert werden:
Hierdurch wird dem select-Attribut ein Wert zugewiesen. Dabei handelt es sich allerdings nicht um einen festen Wert, sondern um einen dynamisch ermittelten. Und zwar wird durch last() die Positionsnummer des letzten Knotens einer Reihe ermittelt. Beachten Sie, dass nicht jeder XSLT-Prozessor alle Funktionen unterstützt. Auf den folgenden Seiten werden die in XPath definierten Funktionen vorgestellt.
46
Operatoren einsetzen
Für Knotenmengen Tabelle 2.3: XPath-Funktionen für Knotenmengen
Funktion
Rückgabewert
Beschreibung
count(Knotenmenge)
Zahl
Ermittelt die Anzahl der auf der Ebene unterhalb eines Knotensets enthaltenen Knoten.
id(Objekt)
Knotenmenge
Ergibt die Menge aller Knoten, die die Elemente des Dokuments enthält, deren Attribut in einer DTD als Attributtyp ID definiert wurde.
last()
Zahl
Ergibt die Anzahl der Knoten in der Kontextknotenliste.
local-name (Knotenmenge)
String
Aus einem Knotennamen mit Namensraumangabe wird der lokale Namensteil ermittelt. Aus xhtml:cite wird so cite.
name(Knotenmenge)
String
Ermittelt den vollständigen Namen eines Knotensets, gegebenenfalls mit Angabe des XMLNamensraums.
namespaceuri(Knotenmenge)
String
Ermittelt den URI für die DTD zum verwendeten Namensraum.
schnell + kompakt
47
2 – Ohne XPath geht es nicht
Für Zahlen Tabelle 2.4: XPath-Funktionen für Zahlen
Funktion
Rückgabewert
Beschreibung
ceiling(Zahl)
Zahl
Angewandt auf X, liefert die Funktion die kleinste Zahl, die größer oder gleich X ist.
floor(Zahl)
Zahl
Rundet eine Bruchzahl zur basierenden Ganzzahl ab.
number(Objekt)
Zahl
Konvertiert ein Objekt in eine Zahl. Strings, die mit einer Zahl beginnen, werden in diese Zahl konvertiert. Andere Strings werden in NaN (Not a Number) konvertiert. true wird in 1, false in 0 umgewandelt. Bei Knotenmengen wird zunächst der String-Wert des ersten Knotens der Menge ermittelt und anschließend in eine Zahl umgewandelt.
round(Zahl)
Zahl
Rundet eine Bruchzahl zur nächstgelegenen Ganzzahl auf.
sum(Knotenmenge)
Zahl
Ermittelt die Gesamtsumme der Zahlenwerte des Ausgangsknotens.
48
Operatoren einsetzen
Für boolesche Werte Tabelle 2.5: XPath-Funktionen für boolesche Werte
Funktion
Rückgabewert
Beschreibung
boolean(Objekt)
Boolean
Ermittelt, ob ein Ausdruck wahr (true) oder falsch (false) ist. Eine Zahl ist immer wahr, wenn sie weder 0 noch NaN ist. Eine Knotenmenge ist immer wahr, wenn sie nicht leer ist. Ein String ist immer wahr, wenn er nicht leer ist.
false()
Boolean
Verneint einen Ausdruck.
lang(String)
Boolean
Kontrolliert, ob in einem Element ein bestimmter Sprachcode verwendet wird. Setzt voraus, dass im Element das XML-Attribut xml: lang definiert ist.
not(Boolean)
Boolean
Gibt den Wert aus, der ungleich dem Parameter ist. Für true wird false, für false wird true ausgegeben.
true()
Boolean
Bejaht einen Ausdruck.
schnell + kompakt
49
2 – Ohne XPath geht es nicht
Für Strings Tabelle 2.6: XPath-Funktionen für Strings
Funktion
Rückgabewert
Beschreibung
concat(String, String...)
String
Hängt mehrere Zeichenketten aneinander.
contains (String, String...)
Boolean
Überprüft, ob eine Zeichenkette eine bestimmte Teilzeichenkette enthält.
normalize-space (String)
String
Führende oder abschließende Leerzeichen werden entfernt. Mehrere aufeinanderfolgende Leerzeichen ersetzt die Funktion durch ein Leerzeichen. Das bedeutet, dass zum Beispiel auch Zeilenumbrüche durch Leerzeichen ersetzt werden.
starts-with (String, String)
Boolean
Ermittelt, ob am Anfang einer Zeichenkette eine bestimmte Teilzeichenkette steht.
string(Objekt)
String
Wandelt das übergebene Objekt in einen String um. Handelt es sich um einen Knoten, wird der Textwert des Knotens ausgegeben. Bei einer Zahl wird die Zahl als Text ausgegeben. Ungültige Zahlen liefern dabei NaN, positive unendliche liefern Infinity und negative unendliche liefern –Infinity. Boolesche Werte werden mit true und false ausgegeben.
50
Operatoren einsetzen Tabelle 2.6: XPath-Funktionen für Strings (Forts.)
Funktion
Rückgabewert
Beschreibung
string-length (String)
Zahl
Ermittelt die Länge der Zeichenkette.
substring (String, Zahl, String)
String
Aus einer Zeichenkette wird ein Teil ab einer bestimmten Zeichenposition extrahiert. Zusätzlich kann die zu extrahierende Zeichenanzahl angegeben werden.
substring-after (String, String)
String
Liefert den Teil des ersten Strings, der sich nach der Position des zweiten Strings befindet. So gibt substringafter("abcdef", "ab") den Wert cdef aus.
substring-before (String, String)
String
Gibt den ersten Teil des Strings aus, der sich vor der Position des zweiten Strings befindet. So gibt substringbefore("abcdef", "cd") den Wert ab aus.
translate (String, String, String)
String
Ersetzt alle Zeichen des zweiten Strings, die sich im ersten String befinden, durch die Zeichen des dritten Strings, die die gleiche Position besitzen, und gibt diesen aus. So gibt translate("abcdef","ace","123") den Wert "1b2d3f" aus.
schnell + kompakt
51
KAPITEL 3 Templates: Vorlagen anlegen 3.1
Templates aufrufen
55
Kernkonzept von XSLT sind Templates. Allerdings ist nicht alles, was im Zusammenhang mit XSLT als Template bezeichnet wird, tatsächlich ein Template. Denn in XSLT muss man zwischen Template und Template Rules (Template-Regeln) unterscheiden. Eine Template Rule definiert Regeln für den Transformationsprozess und besitzt immer ein Template. Bei dem Template selbst handelt es sich um ein Stylesheet, das innerhalb des Ergebnisdokuments instanziiert wird. Template-Regeln sind Vorlagen für die Transformation bestimmter Knoten. Bei diesen Knoten kann es sich zum Beispiel um Elemente oder Attribute handeln. Jede Template-Regel definiert, wie Fragmente für den Ergebnisbaum erzeugt werden sollen. Dabei kann das Fragment sogar leer sein. Ebenso kann der gesamte Ergebnisbaum ausschließlich über eine Template-Regel definiert werden. Innerhalb jeder Template-Regel wird eine Bedingung angegeben, wann sie anzuwenden ist. Das kann ein Muster sein, das auf bestimmte Knoten im Eingabebaum passt. Ebenso kann aber auch ein Name angegeben werden, über den die Regel immer angewendet wird, unabhängig von den Knoten des Eingabebaums.
schnell + kompakt
53
3 – Templates: Vorlagen anlegen
Bei der Verarbeitung eines Dokuments wird für alle Knoten des Eingabebaums nach entsprechenden Template-Regeln gesucht. Dabei wird die Reihenfolge des Eingabedokuments eingehalten, außer es wurde explizit etwas anderes bestimmt. Bereits verarbeitete Knoten werden normalerweise nicht noch einmal transformiert, es sei denn, es wurde auch hier explizit etwas anderes bestimmt. Für die Verarbeitung von Template-Regeln spielt es keine Rolle, an welcher Stelle sie stehen. Das Ergebnis bleibt immer gleich. Innerhalb eines XSLT-Stylesheet können mehrere Template-Regeln enthalten sein, die auf einen Knoten des Ausgangsdokuments passen. In diesen Fällen wird normalerweise nur eine Regel angewendet. Welche das ist, können Sie bestimmen. Definiert werden Template-Regeln über folgendes Element:
Im einleitenden Tag ist immer das Attribut match enthalten. Das gibt an, welches Element der XML-Datei transformiert werden soll. Ein sogenannter Pattern beschreibt eine Regel, nach der eine Template-Regel für einen Knoten ausgewählt wird. Tabelle 3.1: Die zur Verfügung stehenden Pattern
Pattern
Beschreibung
/
Wurzelelement
*
Jedes Element
@*
Jedes Attribut
text()
Textelemente
54
Templates aufrufen Tabelle 3.1: Die zur Verfügung stehenden Pattern (Forts.)
Pattern
Beschreibung
Elementname
Alle Elemente mit dem angegebenen Namen
id(Name)
Alle Elemente, die den Namen Name haben
@Name
Alle Attributknoten mit angegebenen Namen
list-el[position() mod 2 = 1]
Alle ungeraden Elemente
Name1 | Name2
Jedes Element Name1 oder Name2
Name1/Name2
Jedes Element Name2 als Kind von Name1
processing-instruction()
Alle Verarbeitungsanweisungen
node()
Alle Knoten, die keine Attribute oder das Root-Element sind
dem
3.1 Templates aufrufen Nachdem Sie nun wissen, wie Templates arbeiten, geht es in diesem Abschnitt um deren Aufruf. Eingesetzt wird hierfür das XSLT-Element , das die folgenden Attribute kennt: 쐌 select – Hierüber können Sie das Template angeben, das angewendet werden soll. Existiert eine -Definition für das Element, wird sie angewendet. Fehlt das select-Attribut, werden alle nächstuntergeordneten -Definitionen angewendet. 쐌 mode – Das über select angegebene Template wird nur dann gewählt, wenn es den angegebenen Modus hat. Dazu muss bei der Template-Definition mit der Name des Modus über das Attribut modus angegeben werden.
schnell + kompakt
55
3 – Templates: Vorlagen anlegen
gehört zu den am häufigsten benutzten Ele-
menten von XSLT. Einsetzen lässt es sich folgendermaßen:
Durch das Weglassen des select-Attributs wird erreicht, dass die Kindknoten des aktuellen Knotens verarbeitet werden. Im folgenden Beispiel wird die Verwendung von gezeigt. Zunächst die Ausgangsdatei: Es war einguter Autor.
Durch das XSLT-Stylesheet soll Code generiert werden, der folgendermaßen aussieht:
Es war einguter Autor.
Ein Blick auf das Stylesheet zeigt, dass gleich zweimal vorkommt.
56
Templates aufrufen
Zunächst taucht innerhalb der Template-Definition für die Dokumentwurzel auf. Das fehlende select-Attribut bewirkt, dass an den betreffenden Stellen innerhalb des generierten HTML-Codes die Templates für die nächstuntergeordneten Elemente angewendet werden. In dem diesem Beispiel zugrunde liegenden XML-Dokument handelt es sich um das Element . Für alle -Elemente wird über ein eigenes Template definiert. Alle diese Elemente werden im HTML-Code mit
ausgezeichnet. Für die Inhalte dieses Elements müssen allerdings ebenfalls die untergeordneten Templates berücksichtigt werden. Daher ist
schnell + kompakt
57
3 – Templates: Vorlagen anlegen
innerhalb des
-Absatzes die Anweisung zu finden.
Als untergeordnetes Element von ist möglich. Für dieses Element wird über ebenfalls ein Template definiert. Text, der innerhalb dieses Elements steht, wird kursiv dargestellt. Innerhalb das -Elements müssen Sie nicht auf untergeordnete Templates achten, sondern Sie können sich mittels ganz auf die Inhalte des Elements konzentrieren.
Templates einbinden Templates können auch an solchen Stellen verwendet werden, an denen man sie eigentlich nicht einsetzen sollte. Das könnte zum Beispiel nötig sein, wenn keine entsprechenden Knoten vorhanden sind. Umgehen lässt sich dieses Problem über das -Element. Dem wird über das name-Attribut der Name des aufzurufenden Template zugewiesen, der über definiert sein muss. Auch hierzu wieder ein Beispiel. Holger Geiger
Innerhalb des -Elements wurde das Attribut telefon definiert, das als Wert die Telefonnummer des Autors besitzt. Durch die Definition eines XSLT-Stylesheet unter Verwendung von wird die folgende Ausgabe generiert:
58
Templates aufrufen
Holger Geiger, Telefon: 040198998
Dafür muss innerhalb des Stylesheet ein Template definiert und diesem ein Name zugewiesen werden. Im aktuellen Beispiel wird als Name Tname verwendet. Werfen Sie zunächst einen Blick auf das vollständige Stylesheet: , Telefon:
schnell + kompakt
59
3 – Templates: Vorlagen anlegen
Die Namenszuweisung wird innerhalb des -Elements über das Attribut name vorgenommen. Im Template passiert zunächst wenig Spektakuläres. Über wird statischer Text ausgegeben. Interessanter ist das zweite Template, in dem das erste Template über aufgerufen wird. Wichtig dabei: Der Name des aufzurufenden Template muss exakt in der gleichen Schreibweise angegeben werden.
Stylesheets importieren Stylesheets können in andere Stylesheets eingebunden werden. So lässt sich eine einmal definierte Funktionalität an mehreren Stellen nutzen. Eine mögliche Variante zum Einbinden von Stylesheets ist das -Element. (Es gibt ein zweites Element, mit dem sich Stylesheets inkludieren lassen. Ausführliche Informationen dazu im nächsten Abschnitt.) Profitipp Beachten Sie, dass im Konfliktfall Stylesheet-Definitionen, die in der aktuellen Datei definiert wurden, Vorrang vor importierten Stylesheet-Definitionen haben. Dem Attribut href weisen Sie den URI der zu importierenden Stylesheet-Datei zu. Das muss außerhalb von definiert werden. Ein Beispiel: Arno Geiger
Hier wird über das href-Attribut das Stylesheet ausgabe1.xsl aufgerufen und auf die Datei angewendet.
60
Templates aufrufen
Innerhalb dieses Stylesheet wiederum wird über die Stylesheet-Datei ausgabe2.xsl importiert. In dieser Datei ist für das -Element ein Textabsatz definiert. Angewendet wird das Stylesheet genau an der Position, an der steht. Und hier der Vollständigkeit halber noch der Inhalt der Datei ausgabe2.xsl:
schnell + kompakt
61
3 – Templates: Vorlagen anlegen
Mehrere Stylesheets verwenden Eine andere Möglichkeit, einem XSLT-Dokument ein externes Stylesheet zuzuweisen, bietet das Element . Hierdurch kann ein Stylesheet ein anderes Stylesheet inkludieren. Dieses Element erlaubt die Kombination mehrerer Stylesheets, ohne dass dabei die Semantik der einzelnen Stylesheets verändert wird. Das Attribut href erwartet als Wert den URI der zu inkludierenden Stylesheet-Datei. Die in dieser Datei enthaltenen Angaben werden in das aktuelle Dokument eingebunden, und zwar an der Stelle, an der der Aufruf stattgefunden hat. Das -Element ist nur als Element der obersten Ebene erlaubt. Es kann also ausschließlich innerhalb von stehen, muss aber außerhalb von definiert werden. Ein Beispiel: geiger.gif Arno Geiger
In dieser XML-Datei wird über das href-Attribut die StylesheetDatei ausgabe1.xsl eingebunden. Deren Syntax sieht folgendermaßen aus:
62
Templates aufrufen
Die hier über das href-Attribut angegebene XSL-Datei ausgabe2.xsl wird als XML-Dokument analysiert. Die Kindelemente von ersetzen das -Element innerhalb des inkludierten Dokuments.
schnell + kompakt
63
3 – Templates: Vorlagen anlegen
Im aktuellen Beispiel sorgt das inkludierte Stylesheet dafür, dass unterhalb der Grafik ein durch
gekennzeichneter Textabsatz angezeigt wird. Hinweis Beachten Sie, dass ein Stylesheet sich nicht selbst inkludieren darf. Das würde einen Fehler verursachen.
Bedingungen definieren Schleifen Funktionen verwenden Kopieren Sortieren, Gruppieren und Nummerieren Elemente und Attribute erzeugen Die Ausgabe steuern HTML-Ausgabe
71 77 79 82 84 104 111 115
Wenn Sie an dieser Stelle des Buchs angelangt sind, haben Sie die wichtigsten XSLT-Elemente bereits eingesetzt. So kennen Sie zum Beispiel das -Element, das den logischen Einstieg in XSL-Dateien darstellt. Viele der in der folgenden Tabelle zusammengetragenen Elemente werden Ihnen in diesem Buch an der einen oder anderen Stelle begegnen, wo sie auch ausführlich beschrieben werden. In erster Linie dient diese Übersicht dem Nachschlagen, wenn Ihnen bei der Arbeit mit XSLT das passende Element einfach nicht einfallen will. Tabelle 4.1: Die XSLT-Elemente in der Übersicht
Element
Beschreibung
Wendet innerhalb eines über definierten Template extern definierte
Templates
an,
die
mittels
importiert wurden.
schnell + kompakt
65
4 – Mit XSLT arbeiten Tabelle 4.1: Die XSLT-Elemente in der Übersicht (Forts.)
Element
Beschreibung
Hierdurch werden innerhalb eines über definierten Template andere Templates angewendet, die ggf. mit definiert wurden. Hilfreich, um die Reihenfolge der Templates zu steuern.
Ermöglicht das Setzen von Attributen und Werten im Ergebnisbaum.
Ermöglicht die Definition separater Attribute für den Ergebnisbaum.
Hierüber kann man ein anderes Template über dessen Namen aufrufen. An das Template können zudem Parameter übergeben werden.
Das äußere Gerüst für Abfragen, die mit und durchgeführt werden.
So gekennzeichnete Ausgaben werden im Ergebnisbaum in XML- und HTMLgerechte Kommentare eingebettet und sind somit nicht sichtbar. (Zu sehen sind sie ausschließlich im Quelltext.)
Kopiert einen aktuellen Knoten in den Ergebnisbaum an die Stelle, an der die Anweisung steht. Kopiert werden Element-Tags und PCDATA-Inhalt, jedoch weder Attribute noch Kindelemente (siehe ).
Funktioniert wie , es wird aber das gesamte vom Knoten abhängige Knotenset in den Ergebnisbaum kopiert.
66
Mit XSLT arbeiten Tabelle 4.1: Die XSLT-Elemente in der Übersicht (Forts.)
Element
Beschreibung
Hierüber wird ein Schema definiert, in dem Zahlen im Ergebnisbaum ausgegeben werden. Anwenden lässt sich das Schema über die Funktion formatnumber().
Damit wird im Ergebnisbaum ein Element erzeugt.
Für den Fall, dass der XSLT-Prozessor eine XSLT-Anweisung nicht kennt, können Sie hierüber eine Alternativanweisung angeben.
Damit lassen sich Schleifen realisieren, wie sie auch in anderen Programmiersprachen verwendet werden können. Ausführliche Informationen dazu erhalten Sie ab Seite 77.
In XSLT können bedingte Anweisungen definiert werden. Mehr dazu ab Seite 77.
Hierüber kann ein Stylesheet ein anderes Stylesheet inkludieren. Dabei ist dieses Element nur in der obersten Ebene gestattet.
Template-Definitionen aus anderen Stylesheet-Dateien können importiert und dann mittels an der gewünschten Position angewendet werden.
schnell + kompakt
67
4 – Mit XSLT arbeiten Tabelle 4.1: Die XSLT-Elemente in der Übersicht (Forts.)
Element
Beschreibung
Über den damit definierten Schlüssel kann auf Elemente und Attribute zugegriffen werden. Genutzt wird das zum Beispiel für das Gruppieren von Elementen. Informationen dazu erhalten Sie ab Seite 88.
Während der Transformation kann hierüber eine Meldung ausgegeben werden. Als optionales Attribut kann man mit terminate angeben, ob der Transformationsvorgang abgebrochen werden soll.
Damit kann ein Stylesheet in ein anderes transformiert werden.
Ermöglicht die Nummerierung von Elementen. Ausführliche Informationen dazu erhalten Sie ab Seite 92.
Hierüber wird festgelegt, was passieren soll, wenn eine oder mehrere -Bedingungen nicht zutreffen (siehe Seite 92).
Legt fest, wie der Ergebnisbaum ausgegeben bzw. beschrieben werden soll. Weitere Informationen finden Sie ab Seite 111.
Definiert
einen
kann.
68
Parameter, verwendet
der in werden
Mit XSLT arbeiten Tabelle 4.1: Die XSLT-Elemente in der Übersicht (Forts.)
Element
Beschreibung
Legt fest, dass Leerraumzeichen, die zwischen Elementen in der Datei enthalten sind, bei der Ausgabe erhalten bleiben. Leerraumzeichen sind #x20 (einfaches Leerzeichen), #x9 (Tabulatorzeichen), #xD (Wagenrücklaufzeichen) und #xA (Zeilenvorschubzeichen). Über elements werden ein oder mehrere Elemente der Ausgangsdatei angegeben, deren Leerraumzeichen bei der Ausgabe behalten werden sollen. Mehrere Angaben sind durch Leerzeichen zu trennen.
Erzeugt im Ergebnisbaum eine Verarbeitungsanweisung. Das sind spezielle Anweisungen für die auslesende Software. Die Browser reagieren nur auf die Anweisung .
Ermöglicht die sortierte Ausgabe von Daten. Mehr zu diesem Thema ab Seite 85.
Funktioniert ähnlich wie , allerdings werden die Leerraumzeichen in diesem Fall bei der Ausgabe entfernt.
Das ist das Wurzelelement eines XSLStylesheet, in dem sämtliche Style-Definitionen (id, version usw.) enthalten sind.
schnell + kompakt
69
4 – Mit XSLT arbeiten Tabelle 4.1: Die XSLT-Elemente in der Übersicht (Forts.)
Element
Beschreibung
Hierüber werden Templates definiert. Das ist eines der zentralen XSLT-Elemente.
Erlaubt das Erzeugen statischen Textes im Ergebnisbaum. Optional können Sie das Attribut disable-output-escaping angeben, über das bestimmt wird, wie XML-eigene Zeichen behandelt werden. Bei yes werden die Zeichen nicht in ihre benannten Namen umgewandelt, bei no werden sie es.
Das ist ein Synonym für .
Erzeugt eine Zeichenkette an der aktuellen Position des Ergebnisbaums.
Ermöglicht die Definition von Variablen, die in der Datei weiterverwendet werden können. Informationen zu Variablen in XSLT erhalten Sie ab Seite 100.
Ermöglicht innerhalb der Anweisung die Definition einer Bedingung bei einer Mehrfachauswahl. Über den obligatorischen Parameter test wird die Bedingung definiert.
Hierüber wird einem Parameter ein Wert beim Aufruf der Template-Definition zugewiesen.
70
Bedingungen definieren
4.1 Bedingungen definieren Wie nah XSLT echten Programmiersprachen kommt, wird besonders deutlich, wenn Sie sich die Möglichkeiten ansehen, die die Sprache hinsichtlich Schleifen und Fallunterscheidungen zu bietet hat. XSLT kennt die einfache und die komplexe Fallunterscheidung. Die einfache Fallunterunterscheidung ist mit der if-Verzweigung gängiger Programmiersprachen vergleichbar, funktioniert allerdings nur mit einem einzigen Fall. Alternativen wie else und elseif gibt es nicht. Ist eine definierte Bedingung erfüllt, werden die entsprechenden Anweisungen ausgeführt. Die zu erfüllende Bedingung wird innerhalb des Elements über den Wert des Attributs test definiert. Bei diesem Wert handelt es sich um einen Ausdruck, dessen Ergebnis true oder false, also wahr oder falsch ist. So wird durch die folgende Syntax erreicht, dass der Bildname tatsächlich nur dann ausgegeben wird, wenn ein solcher auch definiert wurde. Bidname:
Steht ein boolescher Wert nicht zur Verfügung, wird der Ausdruck in einen booleschen Ausdruck konvertiert. Bei Pfadangaben wird true zurückgeliefert, wenn 쐌 ein Knotentest zurückgeliefert wird, der nicht leer ist, 쐌 eine Zahl zurückgegeben wird, nicht ungleich 0 ist, 쐌 ein String zurückgeliefert wird, der nicht leer ist.
schnell + kompakt
71
4 – Mit XSLT arbeiten
Wie sich die Bedingungen nutzen lassen, zeigt folgendes Beispiel: Geiger Hornby Bryson
Es handelt sich hier um eine einfache XML-Struktur. Die Ausgabe soll so gestaltet werden, dass Kommata und Ausrufezeichen automatisch an der richtigen Position stehen. Die Ausgabe soll folgendermaßen aussehen: Geiger, Hornby, Geiger!
Alle Elemente (unabhängig davon, wie viele es insgesamt sind) sollen jeweils durch Kommata voneinander getrennt werden. Zusätzlich wird nach dem letzten Element ein Ausrufezeichen gesetzt. Um diese Aufgabe zu bewältigen, muss für jedes Element überprüft werden, ob es sich um das letzte der Liste handelt. Diese Aufgabe erledigen die beiden XPath-Funktionen position() und last(), wobei position() die Positionsnummer des aktuellen Knotens und last() die Positionsnummer des letzten von mehreren Knoten eines Knotensets ermittelt. Das vollständige Skript sieht folgendermaßen aus:
72
Bedingungen definieren
Bibliothek Bibliothek , !
Mit position()!=last() wird die Bedingung definiert, dass es sich bei dem aktuellen Element nicht um das letzte Element handelt. Ist diese Bedingung erfüllt, wird ein Komma gesetzt. Die zweite Bedingung position()=last() fragt, ob das aktuelle Element das letzte Element ist. Wenn diese Bedingung erfüllt ist, wird ein Ausrufezeichen gesetzt.
schnell + kompakt
73
4 – Mit XSLT arbeiten
Anstelle eines Ausrufezeichens können Sie auch alle anderen XPath-Operatoren einsetzen. Eine Übersicht dazu finden Sie in Kapitel 3.
Erweiterte Bedingungen definieren Die einfache Variante zur Definition von Bedingungen haben Sie im vorherigen Abschnitt kennengelernt. Allerdings reicht die durch mögliche Auswahl nicht immer bzw. wird die Definition dann schnell umständlich. Um mehrere Bedingungen zu erstellen, gibt es in anderen Programmiersprachen Konstrukte wie if else und if – else if. Über den else-Zweig bestimmen Sie, was passieren soll, wenn keine der zuvor definierten Bedingungen zutrifft. Eine solche komplexe Definition lässt sich auch in XSLT umsetzen. Dabei bildet das Element den Rahmen für eine beliebige Anzahl von Abfragen, die über und durchgeführt werden. Die Abfrage kann aus beliebig vielen -Elementen bestehen, muss aber eine abschließende -Anweisung enthalten. Dabei wird diejenige Abfrage ausgewählt, deren Bedingung als erste erfüllt wird. Die Grundstruktur der Definition einer erweiterten Bedingung sieht in XSLT demnach folgendermaßen aus: ……… ………
74
Bedingungen definieren
……… ………
Während den if-Abfragen anderer Programmiersprachen entspricht, ist mit der else-Klausel vergleichbar. Im folgenden Beispiel werden in einer XML-Datei mehrere -Elemente definiert. 1 5 13 4
Über das XSLT-Stylesheet werden die Werte der -Elemente dahingehend überprüft, ob sie größer oder gleich 10 sind. Je nach Ergebnis wird für jedes -Element entweder unter 10 oder über 10 ausgegeben.
schnell + kompakt
75
4 – Mit XSLT arbeiten
Zahlenspiel (unter 10) (über 10)
Über werden die Werte der -Elemente ausgegeben. Der jeweilige -Wert wird in der Variablen wert gespeichert. Anschließend wird über eine erweiterte Bedingung eingeleitet, in der eine - und eine -Abfrage enthalten sind. Über über-
76
Schleifen
prüft man, ob der Wert der Variablen wert kleiner als 10 ist. Ist das der Fall, wird hinter der Zahl der Text (unter 10) ausgegeben. Ist die Zahl nicht kleiner als 10, erscheint der Text (über 10). Profitipp Es muss übrigens nicht streng zwischen einfacher und komplexer Bedingung unterschieden werden. Oft werden in der Praxis beide Varianten kombiniert. Welche der möglichen Varianten Sie letztendlich einsetzen, hängt von der Art der zu lösenden Aufgabe ab.
4.2 Schleifen Sie kennen Schleifen möglicherweise aus anderen Programmiersprachen. Dort werden sie dazu verwendet, Anweisungen so lange auszuführen, bis ein bestimmter Zustand wahr ist. Genau den gleichen Zweck erfüllen Schleifen auch in XSLT. Für Schleifen gibt es in XSLT das Element . Alles, was innerhalb einer Schleife steht, wird auf sämtliche Knoten innerhalb des Knotensets angewendet. Alle nachfolgenden Knoten werden in der Reihenfolge abgearbeitet, in der sie definiert sind. Im folgenden Beispiel besitzt das Element mehrere Kindelemente . Hornby Ellis
schnell + kompakt
77
4 – Mit XSLT arbeiten
Roth
Um jedes der -Elemente auszugeben, bietet sich der Einsatz einer Schleife an. Die folgende Schleife durchläuft den Knotenbaum, wählt alle -Elemente aus, die Kindelemente von sind, und schreibt diese in den Ergebnisbaum. Bibliothek Bibliothek
78
Funktionen verwenden
Ein anschließender Blick in das Zieldokument zeigt das Ergebnis: Bibliothek Hornby Ellis Roth
Nun ließe sich der gleiche Effekt auch ohne den Einsatz einer Schleife erzielen. Allerdings haben Schleifen den Vorteil, dass sie im Gegensatz zu einem normalen Template mehrere Knotenvorkommnisse an anderen Positionen im Elementbaum erfassen können. Profitipp Beachten Sie, dass es im Gegensatz zu anderen Sprachen in XSLT keine alternativen Schleifen wie while oder for gibt.
4.3 Funktionen verwenden XSLT unterstützt alle XPath-Funktionen, die Sie in diesem Buch bereits kennengelernt haben. Zusätzlich hält XSLT aber noch neun eigene Funktionen bereit. Bevor die Funktionen im Einzelnen vorgestellt werden, ein Beispiel, das die Verwendung von XSLT-Funktionen zeigt. Über die folgende Syntax wird überprüft, ob die Funktion normalize-space() im verwendeten XSLT-Prozessor verfügbar ist:
schnell + kompakt
79
4 – Mit XSLT arbeiten
Verwendet wird dafür die XSLT-Funktion function-available(), der als Wert ein Funktionsname übergeben wird. Die folgende Tabelle enthält die speziellen XSLT-Funktionen: Tabelle 4.2: Die speziellen XSLT-Funktionen
Funktion
Beschreibung
current()
Stellt den Bezug zum aktuellen Knoten her. Als Ergebnis wird das Knotenset geliefert, das den aktuellen Knoten enthält.
document(String)
Ermöglicht es, XML-Ausgangsdaten aus anderen XML-Dateien, als der in das Stylesheet eingebundenen, in den Ergebnisbaum zu übernehmen.
element-available (String)
Ermittelt, ob ein XSLT-Element im verwendeten Parser verfügbar ist.
format-number (Zahl, String)
Konvertiert eine Zahl, unter Verwendung des im zweiten Argument angegebenen Musters, in einen String. Die in der Funktion verfügbaren Formatregeln finden Sie im Anschluss an diese Tabelle.
function-available (String)
Ist dem Prozessor die Funktion mit dem angegebenen Namen bekannt, wird true zurückgeliefert.
80
Funktionen verwenden Tabelle 4.2: Die speziellen XSLT-Funktionen (Forts.)
Funktion
Beschreibung
generate-id(String)
Generiert einen String, der als Wert eines ID-Attributs verwendet wird.
key(String, String)
Alle Knoten, die einen Schlüssel mit dem ersten Argument als Namen und dem zweiten Argument als Wert besitzen, werden als Ergebnis-Knotenmenge erstellt.
system-property()
Ermittelt Informationen über den verwendeten XSLT-Prozessor. XSLT-Prozessoren müssen wenigstens die drei Eigenschaften xsl:version, xsl:vendor und xsl:vendor-url kennen.
unparsed-entity-uri (String)
Ermöglicht den Zugriff auf die DTD-Einträge, die vom Parser analysiert wurden. Gibt es keinen entsprechenden Eintrag, wird ein Leer-String generiert.
Für die in der Tabelle vorgestellte Funktion format-number() können Sie explizit angeben, in welcher Art und Weise die Zahlen dargestellt werden sollen. Hier die möglichen Werte: 쐌 쐌 쐌 쐌 쐌 쐌 쐌 쐌
0 – eine Ziffer # – eine Ziffer, allerdings wird die 0 nicht angezeigt. . – Platzhalter für Dezimalpunkttrennzeichen , – Platzhalter für Gruppierungstrennzeichen ; – mehrere Formate trennen - – negatives Vorzeichen als Voreinstellung % – Wert mit 100 multiplizieren und als Prozentwert anzeigen ? – Wert mit 100 multiplizieren und als Promillewert anzeigen
schnell + kompakt
81
4 – Mit XSLT arbeiten
4.4 Kopieren „Programmier-Feeling“ kommt bei XSLT auf, wenn es ums Kopieren geht. Denn wie in „echten“ Programmiersprachen können Sie auch in XSLT beliebige Elemente kopieren, um diese an anderer Stelle wiederzuverwenden. Mittels können Sie den aktuellen Knoten an die Stelle des Ergebnisbaums kopieren, an der die Anweisung steht. Interessant ist das zum Beispiel, wenn in den XML-Daten Elemente enthalten sind, für die in der Ergebnissprache gleichnamige Elemente existieren. Bei werden die Element-Tags und die PCDATA-Inhalte kopiert. Innerhalb der folgenden XML-Struktur wurden zwei Autorennamen definiert, die jeweils in einem -Tag eingeschlossen sind. Parsons Bryson
Die Autorennamen sollen mitsamt der beiden -Tags direkt in den HTML-Ergebnisbaum kopiert werden. Realisiert wird das über folgendes Stylesheet:
82
Kopieren
Bibliothek
Innerhalb dieses Stylesheet wird für Elemente vom Typ über die Anweisung festgelegt, dass diese in den HTML-Ergebnisbaum kopiert werden. Das Ergebnis entspricht dem, das auch durch die folgende Syntax erreicht werden würde:
Um den gesamten über select ausgewählten Knoten zu kopieren, muss anstelle von das Element verwendet werden. Dabei wird nicht nur der aktuelle Knoten, sondern auch das gesamte von ihm abhängige Knotenset in den Ergebnisbaum kopiert.
schnell + kompakt
83
4 – Mit XSLT arbeiten
Kopieren von Teilbäumen Über können Teilbäume in das Ergebnisdokument kopiert werden. Dabei werden der aktuelle Knoten und das gesamte von ihm abhängige Knotenset an die Stelle im Ergebnisbaum kopiert, an der die Anweisung steht. Diese Syntax ist sinnvoll, wenn Sie den Inhalt eines Elements, das nur einmal in den Daten definiert wurde, an mehreren Stellen verwenden wollen. besitzt das Attribut select, über das angegeben wird, was kopiert werden soll.
Das Attribut select liefert eine Zahl, einen String, einen booleschen Wert oder ein Knotenset.
4.5 Sortieren, Gruppieren und Nummerieren XML-Dokumente im Ergebnisbaum so auszugeben, wie sie im Ausgangsdokument stehen, ist problemlos möglich. Allerdings ist das nicht immer so gewollt. XSLT bietet verschiedene Möglichkeiten, die Art der Ausgabe zu beeinflussen. So können Sie zum Beispiel das Element bestimmen, nach dem die Ausgabe sortiert werden soll. Ein typisches Einsatzgebiet sind hier zum Beispiel Namenslisten, die man im Ergebnisbaum anhand der Nachnamen sortiert. Auf den folgenden Seiten lernen Sie die Möglichkeiten kennen, die XSLT auf den Gebieten Sortieren, Gruppieren und Nummerieren zu bieten hat.
84
Sortieren, Gruppieren und Nummerieren
Daten sortieren Daten können im Ergebnisbaum sortiert werden. Die einfachste Methode zum Umarrangieren von XML-Elementen bietet das Element , das die folgenden Attribute kennt: 쐌 case-order – bestimmt, ob in der Sortierung Großbuchstaben vor Kleinbuchstaben angezeigt werden. Mögliche Werte sind upper-first (Großbuchstaben zuerst) und lower-first (Kleinbuchstaben zuerst). 쐌 data-type – legt fest, ob eine numerische oder alphabetische Sortierung erfolgen soll. Mögliche Werte sind text (alphabetische Sortierung) und number (numerische Sortierung). Zusätzlich soll man in Zukunft auch andere Datentypen angeben können, die in der XML-Spezifikation definiert sind. 쐌 lang – hierüber bestimmen Sie die Sprache, nach deren Konventionen die Sortierung erfolgen soll. Als Wert weisen Sie diesem Attribut ein Sprachkürzel wie en oder de zu. Wenn Sie das Attribut weglassen, wendet der XSLT-Prozessor die Sprache der Systemumgebung an. 쐌 order – über dieses Attribut wird festgelegt, ob die Sortierung aufsteigend (z.B. von A bis Z) oder absteigend (z.B. von Z nach A) erfolgen soll. Mögliche Werte sind ascending (aufsteigend = Voreinstellung) und descending (absteigend). 쐌 select – bestimmt, was sortiert werden soll. Wenn Sie dieses Attribut nicht setzen, ist der Inhalt des betroffenen Elements das, was sortiert werden soll. kann innerhalb der beiden Elemente und vorkommen.
schnell + kompakt
85
4 – Mit XSLT arbeiten
Die folgende Syntax zeigt ein typisches XML-Dokument: One for my baby 3492261469 Piper Eine kurze Geschichte von fast allem 3442460719 Goldmann Verschwörung gegen Amerika 3499240874 Rowohlt
Hier werden einige Autoren definiert, denen jeweils eines ihrer Bücher inklusive ISBN und Verlag zugewiesen wird. So weit also nichts Besonderes. Im Ergebnisdokument soll die Ausgabe allerdings sortiert werden. Als Sortierkriterium dienen dabei die Autorennamen.
86
Sortieren, Gruppieren und Nummerieren
Autor
Titel
ISBN
Verlag
Bryson
Eine kurze Geschichte von fast allem
3442460719
Goldmann
Parsons
One for my baby
3492261469
Piper
Roth
Verschwörung gegen Amerika
3499240874
Rowohlt
Um eine solche Ausgabe zu erhalten, wird die folgende Syntax verwendet: Bibliothek
Autor
Titel
ISBN
Verlag
schnell + kompakt
87
4 – Mit XSLT arbeiten
Das Herzstück dieser Syntax bilden die Elemente und . Über werden die zu bearbeitenden Elemente ausgewählt. Die Sortierung der Einträge übernimmt . Das Beispiel zeigt, wie einfach sich in XSLT Elemente sortieren lassen. Versuchen Sie, Ähnliches mit PHP oder Java umzusetzen, bräuchten Sie ein Vielfaches an Code.
Elemente gruppieren Äußerst problematisch ist das Gruppieren von Elementen. Warum dieses Gruppieren oft nötig und dann so schwierig ist, zeigt ein typisches Beispiel: Oft werden Ergebnisse von Datenbankabfragen in XML geliefert, deren Struktur sich an der Struktur der Datenbank orientiert. Eine typische Rückgabe könnte folgendermaßen aussehen: Ellis Bret Hornby Ellis
88
Sortieren, Gruppieren und Nummerieren
Ellis Michael ...
Die Aufgabe könnte nun darin bestehen, die Datensätze nach dem Nachnamen (nname) zu gruppieren. Für das gezeigte Beispiel sähe eine solche Gruppierung folgendermaßen aus: Ellis, Bret Michael Hornby, Nick
Um eine solche Gruppierung zu realisieren, sind zwei Schritte nötig: 1. Die in der Rückgabe enthaltenen Nachnamen müssen ermittelt werden. 2. Alle Einträge, die den gleichen Nachnamen haben, müssen ermittelt werden. Am effektivsten lässt sich diese Aufgabe mit der Muench’schen Methode lösen, bei der auf Keys (Schlüssel) gesetzt wird. Ein solcher Key weist einem XML-Knoten einen Schlüsselwert zu. Auf Basis dieses Werts wird später der Zugriff auf diesen Knoten ermöglicht. Bei vielen Knoten mit dem gleichen Schlüsselwert werden all diese Knoten anhand dieses Werts ermittelt. Keys sind also bestens für das Gruppieren geeignet. Auf das Autorenbeispiel angewendet, bietet sich ein Schlüssel an, der jedem Datensatz den Namen als Schlüsselwert zuweist.
schnell + kompakt
89
4 – Mit XSLT arbeiten
Das -Element kennt drei Attribute. Über name wird der Name für den Schlüssel festgelegt, unter dem er angewendet werden soll. Die zu gruppierenden Knoten legt man über das matchAttribut fest. Nachdem der Schlüssel definiert wurde, können für einen bekannten Nachnamen alle Einträge ermittelt werden. key('nname', 'ellis')
Diese Syntax liefert alle Autoren mit dem Nachnamen Ellis. Der erste der beiden notwendigen Schritte ist somit erledigt. Im zweiten Schritt müssen alle Einträge ermittelt werden, die den gleichen Nachnamen besitzen.
Dazu müssen zunächst alle verfügbaren Nachnamen, also der jeweils erste Eintrag zu einem bestimmten Nachnamen, ermittelt werden. Auch hierfür eignet sich wieder der Einsatz von Schlüsselwerten. Bekannt ist, dass jeder Datensatz ein Teil der Knotenliste ist, die zurückgeliefert wird, wenn als Schlüsselwert der dazugehörende Nachname verwendet wird. Um zu ermitteln, ob es sich bei einem Eintrag um den ersten der durch einen Schlüssel zurückgegebenen Liste handelt, muss dieser Eintrag mit dem ersten Knoten der Liste verglichen werden. Hierfür gibt es verschiedene Möglichkeiten. Zunächst einmal kann man über generate-id() einen eindeutigen Bezeichner für die beiden Knoten generieren lassen und diese miteinander vergleichen. contact[generate-id() = generate-id(key('autor-name', nname)[1])]
90
Sortieren, Gruppieren und Nummerieren
Eine andere Variante besteht darin, zu überprüfen, ob die Menge aus den zu vergleichenden Knoten exakt ein oder mehrere Elemente enthält. Da innerhalb einer Menge Knoten nicht mehrfach auftreten, ist klar, dass die beiden Knoten identisch sind, wenn nur ein Knoten enthalten ist. contact[count(. | key('autor-name', nname) [1]) = 1]
Die Gruppen wurden ermittelt und können in die gewünschte Reihenfolge gebracht werden. Die folgende Syntax sorgt für die gruppierte Ausgabe, die eingangs dieses Abschnitts gezeigt wurde. , ()
Beachten Sie, dass diese Methode sich nur bei solchen XSLT-Prozessoren anwenden lässt, die Keys unterstützen. (Mittlerweile ist das bei den meisten Prozessoren der Fall.)
schnell + kompakt
91
4 – Mit XSLT arbeiten
Nummerierungen Über können Elemente im Ergebnisbaum mit einer fortlaufenden Nummerierung versehen werden. Interessant ist das zum Beispiel für Listen oder Kapitelüberschriften. Anwendungen wie 1. Eintrag 2. Eintrag 3. Eintrag
sind problemlos möglich. kennt die folgenden Attribute:
쐌 count – gibt das oder die Knotensets bzw. Pfade an, bei denen der Zähler erhöht werden soll. 쐌 format – hierüber wird bestimmt, wie die Nummerierung aussehen soll. Die möglichen Werte finden Sie in der nachfolgenden Tabelle. 쐌 from – legt die Stelle fest, an der die Nummerierung beendet werden soll. 쐌 grouping-separator – damit legen Sie das Trennzeichen für Gruppierungen fest. Ein typisches Beispiel sind Tausendertrennzeichen, die üblicherweise durch einen Punkt (1.000.000) gekennzeichnet werden. 쐌 grouping-size – über dieses Attribut wird die Anzahl der Ziffern festgelegt, bei denen ein Trennzeichen gesetzt wird. Im Fall der Tausenderschritte wäre das die 3. 쐌 lang – hierüber bestimmen Sie die Sprache, nach deren Konventionen die Nummerierung erfolgen soll. Für Deutschland wählen Sie de, für England en usw. 쐌 letter-value – bei einigen Sprachen kann zusätzlich zu lang dieses Attribut mit einem der beiden Werte alphabetical oder
92
Sortieren, Gruppieren und Nummerieren
traditional angegeben werden. Dazu muss die angegebene
Sprache aber auch eine alphabetische bzw. traditionelle Zählweise unterstützen. 쐌 level – legt fest, ob die Aufzählung nur auf einer (single), mehreren (multiple) oder allen (any) Zweigen des Ausgangsdokuments fortgeführt werden soll. 쐌 value – ein Kalkulationsausdruck, über den die Nummerierung bestimmt wird. Über das Attribut format wird die Art der Nummerierung bestimmt. Dabei sind die folgenden Werte möglich: Tabelle 4.3: Die verschiedenen Arten der Nummerierung
Wert
Art der Nummerierung
1
1, 2, 3, 4 …
01
01, 02, 03, 04 …
a
a, b, c, d …
A
A, B, C, D …
i
I, ii, iii, iv …
I
I, II, III, IV …
Auch hierzu wieder ein Beispiel: Arno Geiger Frank Schätzing Francois Lelord
schnell + kompakt
93
4 – Mit XSLT arbeiten
Die im Ausgangsdokument hinterlegten Autorennamen sollen im Ergebnisdokument nummeriert ausgegeben werden. Folgendes Ergebnis ist das Ziel: 1. Arno Geiger 2. Frank Schätzing 3. Francois Lelord
Die Syntax, die das umsetzt, sieht folgendermaßen aus:
94
Sortieren, Gruppieren und Nummerieren
Innerhalb der Template-Definition wird auf das name-Element die -Anweisung angewendet. Um eine einfache Nummerierung zu erhalten, wird dem level-Attribut die Eigenschaft single zugewiesen. Bei jedem Auftreten eines name-Elements soll die Nummerierung fortgesetzt werden (count="link"). Über das letzte Attribut format wird nun noch die Art der Nummerierung bestimmt. Das -Element hat lediglich eine kosmetische Funktion und sorgt dafür, dass nach jedem Element ein Zeilenumbruch eingefügt wird, die Einträge also untereinander stehen.
Variablen und Parameter In XSLT können Parameter und Variablen verwendet werden. Dabei sind Parameter zusätzliche Kontextangaben, über die sich die Template-Instanziierung beeinflussen lässt. Um mit Parametern arbeiten zu können, müssen diese innerhalb des zu instanziierenden Template deklariert sein. Dafür wird im Template das Element verwendet, bei dem zwei Attribute möglich sind. 쐌 name – definiert den Variablennamen. Über diesen Namen kann auf den Wert der Variablen zugegriffen werden. 쐌 select – hierüber bestimmen Sie den Vorgabewert für den Parameter. Wird dieses Attribut angegeben, handelt es sich um einen Parameter, der dafür gedacht ist, von einer TemplateDefinition an eine andere übergeben zu werden. Um das parametrisierte Template zu instanziieren und den Parametern Werte zuzuweisen, wird das Element verwendet. 쐌 name – gibt den Namen des Parameters an. Der muss unter diesem Namen innerhalb der Template-Definition verfügbar sein. Damit er das ist, müssen Sie ihn über definieren.
schnell + kompakt
95
4 – Mit XSLT arbeiten
쐌 select – hierüber wird dem Parameter ein Wert zugewiesen. Das kann zum Beispiel ein Knoten aus einer XML-Datei oder statischer Text sein. Elemente des Typs dürfen nur innerhalb von oder vorkommen. Solche Parameter, die in Top-Level-Elementen des Stylesheet definiert wurden, werden als globale Parameter bezeichnet. Sie legen Vorgaben für das gesamte Dokument fest. Mittlerweile können den meisten XSLT-Prozessoren Werte für globale Parameter zur Verarbeitung von Dokumenten übergeben werden. Wie sich Parameter verwenden lassen, zeigt folgendes Beispiel: 5 20
Innerhalb der XML-Datei werden zwei Zahlenwerte definiert. Dabei bildet begin den Anfangs- und ende den Endwert. Durch das folgende Stylesheet wird eine HTML-Tabelle generiert, in der für alle Ganzzahlen zwischen Anfangs- und Endwert eine Zelle enthalten ist. In jeder dieser Zellen werden die entsprechende Zahl und deren berechnetes Quadrat ausgegeben.
96
Sortieren, Gruppieren und Nummerieren
schnell + kompakt
97
4 – Mit XSLT arbeiten
Fertig!
In der Template-Definition für das Wurzelelement wird über die Template-Definition Durchlauf aufgerufen. Innerhalb von wird der Parameter Zahl definiert, dem als Wert des select-Attributs der Inhalt des beginElements zugewiesen wird. Profitipp Um zu garantieren, dass es sich bei dem Inhalt dieses Elements tatsächlich um eine Zahl handelt, wird die Funktion number() verwendet. In der aufgerufenen Template-Definition Durchlauf wird über der Parameter Zahl definiert. Anschließend wird mittels überprüft, ob der Wert von Zahl kleiner oder gleich dem Wert ist, der im Element ende gespeichert ist. Nur wenn das der Fall ist, wird eine neue Tabellenzelle generiert, in der Zahl und Quadrat ausgegeben werden. Die übrigen Elemente der XSLT-Datei sorgen dann dafür, dass die Schleife um den Wert 1 erhöht und nach Beendigung aller Durchläufe ein treffender Kommentar ausgegeben wird.
98
Sortieren, Gruppieren und Nummerieren
Parameter übergeben Im vorherigen Abschnitt haben Sie den Umgang mit Parametern kennengelernt. Nun geht es um deren Übergabe. Mit wird einem Parameter ein Wert zugewiesen, und zwar genau beim Aufruf der Template-Definition. In der aufgerufenen Template-Definition wird dann, vorausgesetzt, der Parameter ist dort verfügbar, mit dem zugewiesenen Wert gearbeitet. kennt zwei Attribute: 쐌 name – den Parameternamen geben Sie hierüber an. Der Parameter muss innerhalb der Template-Definition unter diesem Namen verfügbar sein. Das ist der Fall, wenn er dort mit definiert wurde. 쐌 select – hierüber wird dem Parameter ein Wert zugewiesen. Dabei kann es sich zum Beispiel um einen Knoten aus der XML-Ausgangsdatei handeln. In diesem Fall ist der Wert des Parameters der Inhalt dieses Knotens. Ebenso können Sie aber auch statischen Text nach dem Schema select="'Hallo, Welt!"' angeben. Dabei ist dann aber unbedingt auf die inneren einfachen Anführungszeichen zu achten. Wenn der Wert des Parameters über select bestimmt wird, erhält man einen der vier Basistypen (String, Zahl, Boolean oder Knotenset) oder – aber nur, wenn eine erweiterte Funktion aufgerufen wird – andere Ergebnistypen. Mit dem erhaltenen Typ wird weitergearbeitet. Im folgenden Beispiel wird ein Parameter übergeben.
schnell + kompakt
99
4 – Mit XSLT arbeiten
Innerhalb dieses Beispiels wurde ein -Tag definiert. Über den Parameter align soll dessen Ausrichtung bestimmt werden. Dieser Parameter kann mit dem Wert right vom Typ String an die zuvor definierte Template-Regel übergeben werden.
Das Element darf innerhalb von oder vorkommen. Variablen verwenden Variablen funktionieren ähnlich wie Parameter. Der einzige Unterschied besteht darin, dass der Wert von als Standardwert angenommen wird. Innerhalb des Template oder Stylesheet, in dem definiert wurde, können also die Parameter als Standardwerte verwendet werden. Profitipp Die Bezeichnung „Variable“ passt hier genaugenommen nicht. Denn der gesetzte Werte lässt sich nicht mehr ändern. Daher entsprechen Variablen in XSLT eher Konstanten. Die Lebensdauer von Variablen beschränkt sich auf ein Template oder Stylesheet. Definieren Sie beispielsweise in einem untergeordneten Template einen neuen Wert für die Variable, wird dadurch nicht der ursprüngliche Variablenwert überschrieben. Ist der Gültigkeitsbereich des neuen Werts beendet, nimmt die Variable wieder ihren ursprünglichen Wert an.
100
Sortieren, Gruppieren und Nummerieren
Um eine Variable zu definieren, wird das Element verwendet, das die folgenden Attribute kennt: 쐌 name – hierüber wird der Name der Variablen angegeben. Unter diesem Namen kann auf den Wert der Variablen zugegriffen werden. 쐌 select – damit bestimmt man den Wert der Variablen. Wenn dieses Attribut angegeben wird, muss das Element leer sein. Wenn es nicht angegeben wird, weisen Sie der Variablen einen Wert zu, indem Sie diesen zwischen Anfangsund End-Tag notieren. Beachten Sie, dass das Element innerhalb von vorkommen und auch innerhalb von stehen kann – ein typisches Beispiel für eine Variablendefinition. @Name="Nick Hornby"
Hier wird die Variable aname definiert. Wie das Beispiel zeigt, erfolgt der Zugriff auf Variablen über das $-Zeichen. Noch einige Worte zum Gültigkeitsbereich: Variablen, die innerhalb eines Elements wie , , o.Ä. definiert sind, gelten ausschließlich innerhalb dieses Elements und dessen Unterelementen.
schnell + kompakt
101
4 – Mit XSLT arbeiten
Leerräume richtig behandeln XML selbst besitzt Regeln zur Behandlung von Leerräumen (Whitespaces). Allerdings stellt XSLT Elemente zur Verfügung, durch die Sie die Behandlung von Leerräumen durch den Parser selbst definieren können. Zum Einsatz können dabei die beiden Elemente 쐌 und 쐌
kommen. Über diese Elemente wird bestimmt, was mit den Leerraumzeichen in der Ausgangsdatei bei der Ausgabe geschehen soll. Leerraumzeichen sind #x20 (einfaches Leerzeichen), #x9 (Tabulatorzeichen), #xD (Wagenrücklaufzeichen) und #xA (Zeilenvorschubzeichen). Profitipp Beachten Sie, dass es hier ausschließlich um die Formatierung der Elemente im Ergebnisbaum geht. Die Leerraumzeichen innerhalb der Elemente bleiben davon unberührt. Zum besseren Verständnis ein typisches Beispiel. Zunächst der Inhalt der eigentlichen XML-Datei: Parsons Ellis
Zwischen den beiden -Elementen wurde eine Leerzeile eingefügt, die so auch in der Ausgabedatei erhalten bleiben soll. Um das zu gewährleisten, wird auf zurückgegriffen.
102
Sortieren, Gruppieren und Nummerieren
Ein anschließender Blick in die generierte Seite zeigt, dass die ursprüngliche Leerzeile immer noch vorhanden ist. Parsons Ellis
Beiden Elementen wird über das elements-Attribut eine Liste von durch Leerzeichen getrennten Elementnamen übergeben. (Im aktuellen Beispiel wurde allerdings nur ein Elementname verwendet.) Bei allen Elementen, die mit ausgestattet sind, werden die Leerzeichen, die zwischen Elementen in der Ausgangsdatei enthalten sind, bei der Ausgabe entfernt.
schnell + kompakt
103
4 – Mit XSLT arbeiten
In Elementen, die mit gekennzeichnet sind, bleiben die Leerraumzeichen hingegen erhalten. Da es sich hierbei um das Standardverhalten von XML handelt, müssen Sie Elemente normalerweise nicht mit versehen. Sie können anstelle einer Elementliste auch das Wildcard-Zeichen (*) verwenden. Dadurch werden die definierten Eigenschaften auf alle Elemente angewendet.
4.6 Elemente und Attribute erzeugen Nachdem Sie den Umgang mit Templates kennengelernt haben, geht es auf den folgenden Seiten um das Erzeugen von Elementen und Attributen sowie deren Ausgabe im Ergebnisbaum.
Elemente erzeugen Elemente können nicht nur einer sauberen Syntax im Ergebnisdokument dienen, sie können auch Knoten erzeugen, die innerhalb des Ausgangsdokuments schon einmal verwendet wurden. Angelegt werden Elemente über . Das Element kennt die folgenden Attribute: 쐌 name – legt den Namen des zu generierenden Elements an. 쐌 namespace – Namensraum, dem das Element angehört. 쐌 use-attribute-sets – hierüber werden Attributsets definiert, die innerhalb des einleitenden Tags des zu erzeugenden Elements verwendet werden. Der Name sollte auf jeden Fall definiert werden. Namensraum und Attributliste müssen Sie hingegen nicht unbedingt verwenden. Innerhalb von können beliebige Elemente wie Texte, Kommentare usw. definiert werden.
104
Elemente und Attribute erzeugen
Durch die Syntax Mein Element
wird im Ergebnisbaum folgendes Element erzeugt: Mein Element
Sinnvoll ist der Einsatz einer solchen Syntax vor allem, wenn verschiedene Attributsets verwendet werden oder mittels XSL ein Ergebnisbaum generiert werden soll, dessen Zielsprache selbst XSL ist.
Attribute erzeugen Ähnlich komfortabel wie Elemente lassen sich in XSLT auch Attribute erzeugen. Im Ergebnisbaum könnte man so zum Beispiel dem -Element das Attribut align mit dem Wert right zuweisen. In XSLT kommt für die Definition von Attributen das Element zum Einsatz. Das Element kennt die folgenden beiden Attribute: 쐌 name – hierüber wird der Namen des Attributs festgelegt. 쐌 namespace – sollte für das Attribut der Namensraum bekannt sein, aus dem es stammt, kann man den entsprechenden URI damit angeben. Durch die folgende Syntax wird im Ergebnisbaum ein -Tag mit dem Attribut align und dem Wert right generiert:
schnell + kompakt
105
4 – Mit XSLT arbeiten
EinWert right Ein Element wird diese Ausgabe erreicht: Ein Element.
Neben dieser einfachen Attributdefinition können Attributlisten ausgegeben werden. Die sind vor allem nützlich, wenn Sie mehrere Attribute schneller verwenden möchten. So müssen Sie die Attribute nur einmal definieren und können sie dann auf einen Schlag zuweisen. Realisieren lässt sich das über das Element , das die folgenden Attribute kennt: 쐌 name – weist dem Attributset einen Namen zu. Über diesen Namen wird das Attributset anschließend verwendet. 쐌 use-attribute-sets – hierüber kann ein anderes Attributset in das aktuelle Attributset eingebunden werden. Um mehrere Attributsets anzugeben, müssen die Namen durch Leerzeichen getrennt werden. Im folgenden Beispiel soll eine typische XML-Struktur in Tabellenform ausgegeben werden.
106
Elemente und Attribute erzeugen
Meisner
Um die Ausgabe der Tabelle zu steuern, sollen im einleitenden
-Tag die drei Attribute border, cellpadding und cellspacing verwendet werden. Bei der Definition dieser drei Attribute bietet sich ein Attributset an. 1 0 0
schnell + kompakt
107
4 – Mit XSLT arbeiten
Noch vor der eigentlichen Template-Definition wird das Attributset tabellen_definition definiert. Innerhalb des -Tag werden über die jeweiligen Attribute bestimmt. Um das Attributset später auf das
Tag anwenden zu können, verwendet man die Anweisung . Hier wird über name das entsprechende Tag (table) und über use-attribute-sets das zu verwendende Attributset ange-
geben.
Statische Texte ausgeben Eine weitere Möglichkeit zur Ausgabe bietet das Element . Hierüber können statische Texte in den Ergebnisbaum geschrieben werden. So können Sie über das XSLT-Stylesheet Texte definieren und diese anschließend im Ergebnisbaum anzeigen.
108
Elemente und Attribute erzeugen
Auch hierzu wieder ein Beispiel: Wo bin ich?
Die XML-Datei enthält nichts Spektakuläres. Und auch die Ausgabe zeigt lediglich das, was innerhalb der Datei definiert wurde. Das aber ändert sich durch den Einsatz von . Die folgende Syntax sorgt dafür, dass zusätzlich zu den definierten XML-Elementen der URL der aktuellen Seite ausgegeben wird.
schnell + kompakt
109
4 – Mit XSLT arbeiten
" + document.URL + ""); //-->
Die Ausgabe der Datei sieht folgendermaßen aus: Wo bin ich? http://www.entickler-press.com/ausgabe.xml
Erreicht wurde diese Ausgabe durch das Element , über das ein JavaScript-Skript eingefügt wurde. Dieses Skript sorgt über document.URL für die Anzeige des URL der aktuellen Seite. Auch wenn der JavaScript-Code etwas abstrakt wirken mag: Ein Blick in den generierten Code bringt Klarheit über die Syntax: document.write("
" + document.URL + "");
Das Element kennt zusätzlich das Attribut disableoutput-escaping, über das die Behandlung von XML-eigenen Zeichen wie < und > gesteuert wird. Mögliche Werte sind yes und no. Bei yes werden die Zeichen nicht in ihre benannten Zeichen umgewandelt, bei no werden sie es.
110
Die Ausgabe steuern
Text vom Parser generieren lassen Das Element haben Sie im vorherigen Abschnitt kennengelernt. Dadurch lässt sich statischer Text erzeugen und im Ergebnisbaum ausgeben. Darüber hinaus können Sie Text aber auch automatisch vom Parser generieren lassen. Realisiert wird das über eine Kombination aus dem Element und dessen select-Attribut. Sobald dieses Element auftaucht, wird der Wert des durch select beschriebenen Knotens an dieser Stelle ausgegeben. Auch hierzu wieder ein Beispiel: Autor:
Diese Syntax sorgt für folgende Ausgabe: Autor: Tony Parsons
Bei der Wertzuweisung an das select-Attribut gilt die XPathSyntax.
4.7 Die Ausgabe steuern Über das Element können Sie gezielt festlegen, wie der Ergebnisbaum ausgegeben bzw. geschrieben werden soll. So
schnell + kompakt
111
4 – Mit XSLT arbeiten
können Sie beispielsweise bestimmen, ob eine XML-Deklaration ausgegeben wird und mit welcher Kodierung der Ergebnisbaum geschrieben wird. Wie interessant aber tatsächlich ist, zeigt das Beispiel in diesem Abschnitt, bei dem aus einer deutschsprachigen Ausgangsdatei ein englischsprachiger Ergebnisbaum wird. Zunächst aber ein Blick auf die Attribute, die bei möglich sind: 쐌 method – legt die Art fest, in der der Ergebnisbaum erzeugt werden soll. Mögliche Werte sind xml, html (Standard), text oder öffentliche bzw. eigene Namensräume. 쐌 cdata-section-elements – gibt bei method="xml" die Elemente an, deren Inhalte beim Anlegen des Ergebnisbaums in CDATAAbschnitte geschrieben werden sollen. 쐌 encoding – hierüber wird die Kodierung bestimmt, in der der Ergebnisbaum kodiert wird. Standardmäßig wird UTF-8 angenommen, Sie können aber zum Beispiel auch ISO-8859-1 festlegen. 쐌 indent – verwendet man den Wert yes, werden im Ergebnisbaum untergeordnete Elemente eingerückt dargestellt. Diese Angabe ist von Vorteil, wenn Sie den Quelltext lesbarer haben wollen. Auf die Darstellung selbst hat diese Angabe keine Auswirkungen. 쐌 doctype-public – sollte sich die Gültigkeitsprüfung des Ergebnisbaums auf eine öffentliche DTD beziehen, wird diesem Attribut bei method="xml" und method="html" die Zeichenkette des Public Identifier zugewiesen. 쐌 doctype-system – wenn sich die Gültigkeitsprüfung des Ergebnisbaums auf eine adressierte DTD bezieht, wird diesem Attribut bei method="xml" und method="html" die Zeichenkette des System Identifier zugewiesen.
112
Die Ausgabe steuern
쐌 media-type – hierüber geben Sie den MIME-Typ des Ergebnisbaums an. Bei method="html" ist es beispielsweise text/html, bei method="xml" ist es üblicherweise text/xml und bei method="text" lautet er meistens text/plain. 쐌 omit-xml-declaration – bei method="xml" wird festgelegt, ob im Ergebnisbaum eine XML-Deklaration () ausgegeben werden soll. Mögliche Werte sind yes (ohne XML-Deklaration) und no (mit XML-Deklaration). Hinweis Das ist übrigens kein Schreibfehler. Denn omit steht hier für weglassen. yes bedeutet somit, dass die XML-Deklaration weggelassen werden soll. 쐌 version – bei omit-xml-declaration="no" legt man hierüber die XML-Versionsangabe fest. 쐌 standalone – bestimmt bei omit-xml-declaration="no", dass sich die DTD-Deklarationen innerhalb der aktuellen Datei befinden. Ein schönes Beispiel für den Einsatz von ist die folgende Syntax, bei der von dieser XML-Struktur ausgegangen wird: Bill Bryson
schnell + kompakt
113
4 – Mit XSLT arbeiten
Es handelt sich um eine denkbar einfache XML-Datei, in der die Elemente , und enthalten sind. Um die Seite englischsprachigen Kunden schmackhaft zu machen, sollen diese Elemente ins Englische übersetzt werden. Die Übersetzung wird allerdings nicht in der XML-Datei vorgenommen, sondern vollständig über eine XSLT-Datei gesteuert. Kernpunkt dieser Anwendung ist .
114
HTML-Ausgabe
Um einen entsprechenden Ergebnisbaum zu bekommen, werden dem -Element die beiden Attribute method="xml" und indent="yes" zugewiesen. Ein anschließender Blick in den Browser zeigt, dass das Ergebnis genauso wie das Ausgangsdokument aussieht, nun allerdings englischsprachige Elemente enthält. Bill Bryson
Auf diese Weise können Sie auch komplexeste Strukturen in andere Sprachen übersetzen, ohne etwas am Ausgangsdokument ändern zu müssen.
4.8 HTML-Ausgabe Nun, da das Ende des Buchs fast erreicht ist, noch einige typische Beispielanwendungen, die man erfahrungsgemäß im Zusammenhang mit XSLT immer mal wieder braucht. Um die Beispiele in Aktion zu sehen, sollten Sie sie am besten durch einen XSLTProzessor (z.B. Saxon) laufen lassen. (Im Browser funktionieren sie aber auch.)
Formatierte Texte ausgeben Die normale Ausgabe des Ausgangsdokuments ist, wie Sie in diesem Buch immer wieder gesehen haben, relativ einfach. Aller-
schnell + kompakt
115
4 – Mit XSLT arbeiten
dings wirken die Ergebnisdokumente dann meistens etwas schmucklos. Durch den Einsatz von CSS-Stylesheets in Verbindung mit XSLT lassen sich aber durchaus auch optisch ansprechende Ergebnisse erzielen. Als Ausgangspunkt dient das folgende einfache XML-Dokument: Unsere neuesten Bücher Das neue Java-6-Buch von Dirk Frischalowski ist eine fundierte Einführung mit viel Augenmerk auf OOP und Anwendungsaufteilung. Alles wird von der Kommandozeile aus gemacht. Viele Beispiele erleichtern das Verständnis, die Übungen führen in nummerierten Arbeitsschritten zu Lösungen hin. 39 Euro
Für die formatierte Ausgabe ist die folgende XSLT-Datei verantwortlich:
116
HTML-Ausgabe
Um den Text optisch aufzuwerten, werden die auszugebenden XSLT-Elemente jeweils von CSS-Anweisungen umschlossen. Auf die eigentliche XSLT-Syntax muss an dieser Stelle sicherlich nicht noch einmal eingegangen werden. Entscheidend ist vielmehr, dass Sie innerhalb von XSLT-Dateien die Elemente mittels CSS genauso wie in normalen HTML-Dateien formatieren können.
schnell + kompakt
117
4 – Mit XSLT arbeiten
Links und Grafiken ausgeben Bislang beschränkte sich die Ausgabe fast ausnahmslos auf schnöden Text. Das eignet sich zwar hervorragend, um die Sprachelemente von XSLT kennenzulernen, so richtig was her macht es optisch allerdings nicht. In diesem Abschnitt erfahren Sie, wie Sie aus normalen XML-Text Hyperlinks und Grafiken machen können. Dafür ist keine Magie nötig, es reicht einfache XSLT-Syntax. Zunächst das Ausgangsdokument: images/hornby.gif Unter http://www.penguin.co.uk/ static/cs/uk/0/ minisites/nickhornby/index.html finden Sie weiterführende Informationen
Neben dem Wurzelelement enthält diese XMLStruktur die beiden Elemente und . Aus images/hornby.gif soll im Ergebnisdokument ein vollständiges -Tag werden, über das eine Grafik eingebunden wird. Das -Element wiederum wird zu einem echten anklickbaren Hyperlink gemacht. Beide Anforderungen erfüllt das folgende Stylesheet:
118
HTML-Ausgabe
<
Um aus dem -Element einen Hyperlink zu machen, muss der Elementinhalt gleich zweimal ausgegeben werden: einmal als Wert des href-Attributs und einmal als Inhalt des -Elements. Dazu notieren Sie zunächst das -Element. Anschließend wird das Attribut href über die Anweisung definiert. Der Inhalt zwischen einleitendem - und schließendem -Element ist der Wert, der dem href-Attribut zugewiesen werden soll. Im aktuellen Beispiel wird über bestimmt, dass es sich bei diesem Wert um den Inhalt des -Elements
schnell + kompakt
119
4 – Mit XSLT arbeiten
handelt. Um den Inhalt des -Elements zusätzlich als Hyperlinktext anzeigen zu lassen, wird nach dem schließenden , aber noch vor dem abschließenden -Tag angegeben. Für die Bildanzeige gehen Sie synchron vor. Auch hier wird zunächst das eigentliche Tag () notiert. Anschließend weisen Sie das Attribut src und als Attributwert den Inhalt des Elements zu.
descendant 33 descendant-or-self 33 document() 80 DTD 22 URI für Namensraum ermitteln 47 Zugriff auf Einträge 81
id() 47
E element-available() 80 Elemente 104 erzeugen 104 Elementknoten 28 elements node 28 Elternknoten 33 Ergebnisbaum 85 sortieren 85 Text ausgeben 108 eXtensible Stylesheet Language
importieren 60 über Namen aufrufen 66 Textknoten 29 Transformation 12 Funktionsweise 13 Meldung ausgeben 68 verschiedene Arten der 12 translate() 51 true() 49