Lösungen zu den Aufgaben aus XSLT und XPath – der Start
(Auszug aus "XSLT 2.0 & XPath 2.0" von Frank Bongers, Kapitel 1.)
Die Aufgabenstellungen zu den folgenden Lösungen finden Sie unter Aufgaben.
Aufgabe 1a: Stringwert ausgeben:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/1999/xhtml">
<xsl:output method="xhtml" encoding="ISO-8859-1" indent="yes" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" />
<xsl:template match="/">
<html>
<head>
<title>XSLT 2.0 und XPath 2.0: Stringwert 1a)</title>
</head>
<body>
<h1>Memo:</h1>
<p><xsl:value-of select="memo"/></p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Code-Beispiel: loesungen/01/memo1.xsl.
Hier wurde die Template-Regel mit match="/" auf den Dokumentknoten ausgerichtet. Von diesem als Current Node ausgehend, kann der Stringwert des Dokumentinhalts innerhalb eines <p>-Containers als Literal Result Element mit <xsl:value-of select="memo"/> ausgelesen werden.
Alternativ könnte die Template-Regel auf match="memo" gesetzt werden. In diesem Fall würde der Dokumentknoten durch die entsprechende Default-Regel verarbeitet und die reale Template-Regel durch diese aufgerufen werden. Der Stringwert müsste, da <memo> selbst nun Current Node wäre, allerdings mit <xsl:value-of select="."/> extrahiert werden.
Aufgabe 1b: Stringwert ausgeben, alternative Version
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/1999/xhtml">
<!-- Output-Deklaration siehe 1.a) -->
<xsl:template match="/">
<html>
<head>
<title>XSLT 2.0 und XPath 2.0: Stringwert 1b)</title>
</head>
<body>
<h1>Memo:</h1>
<p><xsl:apply-templates/></p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Code-Beispiel: loesungen/01/memo1b.xsl.
Der Unterschied zur vorigen Lösung ist lediglich die Verwendung von <xsl:apply-templates/> anstelle von <xsl:value-of select="memo"/>. Hier wird allerdings nicht direkt ein Stringwert extrahiert, sondern eine Kaskade von Default-Regeln aufgerufen, die letztlich, da für keine Knoten explizite Template-Regeln vorliegen, alle Textknoten des Quelldokuments inklusive der Whitespace Nodes ins Ergebnisdokument kopieren.
Aufgabe 2a: Stringwerte der Einzelelemente ausgeben
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/1999/xhtml">
<!-- Output-Deklaration siehe 1.a) -->
<xsl:template match="/">
<html>
<head>
<title>XSLT 2.0 und XPath 2.0: Stringwert 2a)</title>
</head>
<body>
<h1>Memo:</h1>
<p><xsl:value-of select="memo/an"/></p>
<p><xsl:value-of select="memo/von"/></p>
<p><xsl:value-of select="memo/betreff"/></p>
<p><xsl:value-of select="memo/text"/></p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Code-Beispiel: loesungen/01/memo2.xsl.
Wollen Sie die Stringwerte in Einzelcontainer ausgeben, so muss dies mit mehreren Instruktionen geschehen. Hierbei muss der Pfad vom Current Node zu den Elementknoten berücksichtigt werden. Dieser führt in diesem Fall vom Dokumentknoten über das Wurzelelement.
Wurde die Template-Regel auf match="memo" gesetzt, so ist <memo> Current Node, und zum Auslesen würde jeweils der Bezeichner des Kindelements genügen: <xsl:value-of select="an"/> etc.
Aufgabe 2b: Reihenfolge kontrollieren
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/1999/xhtml">
<!-- Output-Deklaration siehe 1.a) -->
<xsl:template match="/">
<html>
<head>
<title>XSLT 2.0 und XPath 2.0: Reihenfolge 2b)</title>
</head>
<body>
<h1>Memo:</h1>
<p><b>Von: </b><xsl:value-of select="memo/von"/></p>
<p><b>An: </b><xsl:value-of select="memo/an"/></p>
<p><b>Betreff: </b><xsl:value-of select="memo/betreff"/></p>
<p><xsl:value-of select="memo/text"/></p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Code-Beispiel: loesungen/01/memo2b.xsl.
Da die Instruktion xsl:value-of direkt in das Quelldokument greift, muss für eine Variation der Ausgabereihenfolge lediglich die Position der entsprechenden Instruktion in der Template-Regel geändert werden. Entscheidend ist die, den erforderlichen XPath-Ausdruck bestimmende, hierarchische Position der gewünschten Information gegenüber dem Current Node, nicht ihre Position in der Dokumentreihenfolge des Quelldokuments.
Aufgabe 2c: Reihenfolge kontrollieren, alternative Version
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/1999/xhtml">
<!-- Output-Deklaration siehe 1.a) -->
<xsl:template match="/">
<html>
<head>
<title>XSLT 2.0 und XPath 2.0: Reihenfolge 2c)</title>
</head>
<body>
<h1>Memo:</h1>
<p><b>Von: </b><xsl:apply-templates select="memo/von"/></p>
<p><b>An: </b><xsl:apply-templates select="memo/an"/></p>
<p><b>Betreff: </b><xsl:apply-templates select="memo/betreff"/></p>
<p><xsl:apply-templates select="memo/text"/></p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Code-Beispiel: loesungen/01/memo2c.xsl.
Die gleiche Wirkung mit xsl:apply-templates zu erzielen, erfordert ähnlichen Aufwand. Auch hier bestimmt die Position der Instruktion die Ausgabereihenfolge. Die Extraktion des Werts erfolgt hier jedoch nicht unmittelbar, sondern durch die jeweils gezielte Zusammenstellung einer Nodesequenz aus den gewünschten Elementen (diese Sequenzen umfassen immer nur einen Knoten). Die so zur Verarbeitung angebotenen Knoten werden von den entsprechenden Default-Regeln verarbeitet.
Aufgabe 3: Mehrfachverwendung von Inhalten
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/1999/xhtml">
<xsl:output method="xhtml" encoding="ISO-8859-1" indent="yes" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" />
<xsl:template match="/">
<html>
<head>
<title>
<xsl:text>Memo von </xsl:text>
<xsl:value-of select="memo/von"/>
<xsl:text> an </xsl:text>
<xsl:value-of select="memo/an"/>
</title>
</head>
<body>
<h1>Memo:</h1>
<p><b>Von: </b><xsl:apply-templates select="memo/von"/></p>
<p><b>An: </b><xsl:apply-templates select="memo/an"/></p>
<p><b>Betreff: </b><xsl:apply-templates select="memo/betreff"/></p>
<p><xsl:apply-templates select="memo/text"/></p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Code-Beispiel: loesungen/01/memo3.xsl.
Die Ausgabe im Dokumentkopf der HTML-Seite wird mit xsl:value-of vorgenommen, da hier in jedem Fall nur Strings gebraucht werden. Die Ausgabe des Dokumentrumpfs wurde gegenüber der vorigen Lösung nicht weiter geändert.
Aufgabe 4a: Mehrere Template-Regeln
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/1999/xhtml">
<xsl:output method="xhtml" encoding="ISO-8859-1" indent="yes" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" />
<xsl:template match="/">
<html>
<head>
<title>
<xsl:text>Memo von </xsl:text>
<xsl:value-of select="memo/von"/>
<xsl:text> an </xsl:text>
<xsl:value-of select="memo/an"/>
</title>
</head>
<body>
<h1>Memo:</h1>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="an">
<p><b>An: </b><xsl:apply-templates/></p>
</xsl:template>
<xsl:template match="von">
<p><b>Von: </b><xsl:apply-templates/></p>
</xsl:template>
<xsl:template match="betreff">
<p><b>Betreff: </b><xsl:apply-templates/></p>
</xsl:template>
<xsl:template match="text">
<p><xsl:apply-templates/></p>
</xsl:template>
</xsl:stylesheet>
Code-Beispiel: loesungen/01/memo4.xsl.
Hier wurde für jedes auszugebende Element eine eigene Template-Regel geschrieben, die die im jeweiligen Zusammenhang auszugebenden Literal Result Elements und eine xsl:apply-templates-Instruktion enthält.
Da die Ausgabe in Dokumentreihenfolge bleiben kann, wurde (vergleichbar mit Lösung 1b) eine xsl:apply-templates-Instruktion in der Template-Regel für den Dokumentknoten eingesetzt. Diese stellt eine Nodesequenz zusammen, die den Elementknoten <memo> enthält, der von der Default-Regel für Elementknoten verarbeitet wird. Diese stellt danach die Nodesequenz zusammen, die die weiteren Template-Regeln aktiviert.
Aufgabe 4b: Mehrere Template-Regeln, Reihenfolge kontrollieren
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/1999/xhtml">
<xsl:output method="xhtml" encoding="ISO-8859-1" indent="yes" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" />
<xsl:template match="/">
<html>
<title>
<xsl:text>Memo von </xsl:text>
<xsl:value-of select="memo/von"/>
<xsl:text> an </xsl:text>
<xsl:value-of select="memo/an"/>
</title>
<body>
<h1>Memo:</h1>
<xsl:apply-templates select="memo/von"/>
<xsl:apply-templates select="memo/an"/>
<xsl:apply-templates select="memo/betreff"/>
<xsl:apply-templates select="memo/text"/>
</body>
</html>
</xsl:template>
<xsl:template match="an">
<p><b>An: </b><xsl:apply-temp¬lates/></p>
</xsl:template>
<xsl:template match="von">
<p><b>Von: </b><xsl:apply-tem¬plates/></p>
</xsl:template>
<xsl:template match="betreff">
<p><b>Betreff: </b><xsl:apply-templates/></p>
</xsl:template>
<xsl:template match="text">
<p><xsl:apply-templa¬tes/></p>
</xsl:template>
</xsl:stylesheet>
Code-Beispiel: loesungen/01/memo4b.xsl.
Die Variante mit veränderter Reihenfolge erfordert die Zusammenstellung von spezifischen Nodesequenzen in der gewünschten Abfolge. Dies entspricht der Lösung 2c mit dem Unterschied, dass in diesem Falle explizite Template-Regeln für die einzelnen Elemente vorhanden sind.
Aufgabe 5: Attribute auslesen, Output HTML
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- Beachten Sie das Fehlen des Default-Namensraums! -->
<!-- KEINE Output-Deklaration, d.h. HTML-Erzeugung -->
<xsl:template match="/">
<html>
<head>
<title>XSLT 2.0 und XPath 2.0: Buchdatei 5)</title>
</head>
<body>
<h2><xsl:value-of select="buch/@autor"/><xsl:text>: "</xsl:text><xsl:value-of select="buch/@titel"/><xsl:text>"</xsl:text></h2>
<p><xsl:text>in der Übersetzung von </xsl:text><i><xsl:value-of select="buch/@übersetzer"/></i></p>
<p><xsl:value-of select="buch/@verlag"/><xsl:text>, </xsl:text><xsl:value-of select="buch/@ersch-jahr"/></p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Code-Beispiel: loesungen/01/buch-attrib-html.xsl.
Das Auslesen von Attributen unterscheidet sich nicht wesentlich vom Auslesen des Stringwerts von Elementen. Der Unterschied besteht darin, dass im entsprechenden Location Step auf die Attributachse gewechselt werden muss. Das Ergebnis zeigt den üblichen Meta-Tag für HTML-Content. Umlaute werden mit Entities umschrieben, das Encoding ist UTF-8.
Ergebnis:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>XSLT 2.0 und XPath 2.0: Buchdatei 5)</title>
</head>
<body>
<h2>Mike Miller: "XML – Das verflixte Attribut"</h2>
<p>in der Übersetzung von <i>Peter Panter</i></p>
<p>Galileo Verlag, 2010</p>
</body>
</html>
Code-Beispiel: loesungen/01/buch-attrib-html.html.
Aufgabe 6a: Verwendung von xsl:output, method="xhtml"
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/1999/xhtml">
<!-- Default-Namensraum für XHTML gesetzt -->
<!-- Output-Steuerung XHTML: -->
<xsl:output method="xhtml" encoding="ISO-8859-1" indent="yes" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" />
<xsl:template match="/">
<html>
<head>
<title>XSLT 2.0 und XPath 2.0: Buchdatei 6a)</title>
</head>
<body>
<h2><xsl:value-of select="buch/@autor"/><xsl:text>: "</xsl:text><xsl:value-of select="buch/@titel"/><xsl:text>"</xsl:text></h2>
<p><xsl:text>in der Übersetzung von </xsl:text><i><xsl:value-of select="buch/@übersetzer"/></i></p>
<p><xsl:value-of select="buch/@verlag"/><xsl:text>, </xsl:text><xsl:value-of select="buch/@ersch-jahr"/></p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Code-Beispiel: loesungen/01/buch-attrib-xhtml.xsl.
Dank des entsprechend eingesetzten xsl:output unterscheidet sich die XHTML-Version in 6a) von der Lösung 5) in bestimmten Details. Diese bestehen im vorangestellten XML-Prolog, der DOCTYPE-Deklaration, dem XHTML-Namensraum im Wurzelelement und der Nichtverwendung von HTML-Entities für die Umlaute in der Datei. Hier wird ebenfalls der Content-Meta-Tag eingefügt, jedoch mit dem angeordneten Encoding ISO-8859-1.
Ergebnis:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml; charset=ISO-8859-1"/>
<title>XSLT 2.0 und XPath 2.0: Buchdatei 6a)</title>
</head>
<body>
<h2>Mike Miller: "XML – Das verflixte Attribut"</h2>
<p>in der Übersetzung von <i>Peter Panter</i></p>
<p>Galileo Verlag, 2010</p>
</body>
</html>
Code-Beispiel: loesungen/01/buch-attrib-xhtml.html.
Aufgabe 6b: Verwendung von xsl:output, method="xml"
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- Beachten Sie das Fehlen des Default-Namensraums! -->
<!-- Output-Steuerung XML: -->
<xsl:output method="xml" encoding="ISO-8859-1" indent="yes"/>
<xsl:template match="/">
<html>
<head>
<title>XSLT 2.0 und XPath 2.0: Buchdatei 6b)</title>
</head>
<body>
<h2><xsl:value-of select="buch/@autor"/><xsl:text>: "</xsl:text><xsl:value-of select="buch/@titel"/><xsl:text>"</xsl:text></h2>
<p><xsl:text>in der Übersetzung von </xsl:text><i><xsl:value-of select="buch/@übersetzer"/></i></p>
<p><xsl:value-of select="buch/@verlag"/><xsl:text>, </xsl:text><xsl:value-of select="buch/@ersch-jahr"/></p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Code-Beispiel: loesungen/01/buch-attrib-xml.xsl.
Wird das Dokument mit method="xml" ausgegeben, so kann der XHTML-Namensraum entfallen Er muss Jedoch nicht. In diesem Fall erhält man auf Umwegen ebenfalls ein XHTML-Dokument, allerdings ohne Doctype-Deklaration. Eine Maskierung der Umlaute durch HTML-Entities findet hier selbstverständlich ebenfalls nicht statt.
Ergebnis:
<?xml version="1.0" encoding="ISO-8859-1"?>
<html>
<head>
<title>XSLT 2.0 und XPath 2.0: Buchdatei 6b)</title>
</head>
<body>
<h2>Mike Miller: "XML – Das verflixte Attribut"</h2>
<p>in der Übersetzung von <i>Peter Panter</i></p>
<p>Galileo Verlag, 2010</p>
</body>
</html>
Code-Beispiel: loesungen/01/buch-attrib-xml.html.
In diesem Fall fehlt dem Dokument der XHTML-Namensraum und der für HTML- und XHTML-Ausgabe automatisch eingefügte Content-Type-Meta-Tag: Dies ist für den XSLT-Prozessor also »nur« ein XML-Dokument, das zufällig HTML-Tag-Namen verwendet.
Aufgabe 6c: Verwendung von xsl:output, method="text"
Wird das Dokument mit gleich lautendem Stylesheet, allerdings mit modifizierter Output-Deklaration, die jetzt das Format "text" nennt, verarbeitet:
...
<xsl:output method="text" encoding="ISO-8859-1" indent="yes"/>
...
Code-Beispiel: loesungen/01/buch-attrib-text.xsl (Auszug).
… so erhalten Sie ein einfaches Textdokument aus den String-Inhalten des Quelldokuments und der Literal Result Elements des Stylesheets. Das indent-Attribut wird ignoriert und alle HTML-Tags werden verworfen.
Ergebnis:
BuchdateiMike Miller: "XML – Das verflixte Attribut"
in der Übersetzung von Peter Panter, Galileo Verlag, 2010
Code-Beispiel: loesungen/01/buch-attrib-text.txt.
Dass das encoding-Attribut dagegen nicht ignoriert wird, zeigt sich, wenn man es versuchsweise weglässt. Auch xsl:text-Instruktionen wurden hier entfernt. Dies führt dazu, dass die ansonsten – erwünscht – wegfallenden Zeilenumbrüche im Ergebnis landen:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- Output-Steuerung Text: -->
<xsl:output method="text"/>
<xsl:template match="/">
<html>
<head>
<title>XSLT 2.0 und XPath 2.0: Buchdatei 6c)</title>
</head>
<body>
<h2><xsl:value-of select="buch/@autor"/>:
"<xsl:value-of select="buch/@titel"/>"
</h2>
<p>in der Übersetzung von
<i><xsl:value-of select="buch/@übersetzer"/></i></p>
<p><xsl:value-of select="buch/@verlag"/>,
<xsl:value-of select="buch/@ersch-jahr"/></p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Code-Beispiel: loesungen/01/buch-attrib-text-b.xsl.
Die sich so ergebende Textdatei sieht nun folgendermaßen aus. Beachten Sie die Wirkung des fehlenden Encodings auf die Umlaute:
Ergebnis:
BuchdateiMike Miller:
"XML – Das verflixte Attribut"
in der Ãœbersetzung von
Peter PanterGalileo Verlag,
2010
Tipp der data2type-Redaktion: Zum Thema XSLT bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an: |
Copyright © Galileo Press, Bonn 2008
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "XSLT 2.0 & XPath 2.0 ― Das umfassende Handbuch" denselben Bestimmungen wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.
Galileo Press, Rheinwerkallee 4, 53227 Bonn