eXtensible Stylesheet Language
Was ist XSL?
Analogie zu CSS in HTML
XSL ist eine Sprache, die ein wohlgeformtes XML-Dokument in ein neues Dokument
transformiert
Wunsch: Trennung von Daten und Präsentation
XSL ist für optische Gestaltung eines
Dokuments zuständig
Entwurfsziele für XSL
XSL in bekannter XML-Syntax
XSL als Auszeichnungssprache mit allen wichtigen und gebräuchlichen
Formatierungsbefehlen
möglichst geringe Anzahl optionaler Features
XSL Stylesheets sollen leicht verständlich und gut lesbar sein
schnelle und unkomplizierte Umsetzung
XSL Spezifikation
1. Benutzung sogenannter Formatting Objects (FO)
auf das Erzeugen von Präsentationsdaten ausgerichtet
nicht sehr verbreitet
werden kaum von den gängigen XSL Prozessoren und Tools unterstützt
2. Erstellen von XSLT Stylesheets
XSLT Empfehlung des W3C (21.Nov.2000)
XSL Transformations (=XSLT)
Die Komponenten von XSL
XPath:
Sprache zum Herausgreifen von bestimmten Teilen aus einem Dokument (Traversieren in Dokumentbäumen)
XSLT:
Sprache, die beschreibt, wie man ein XML- Dokument in ein anderes Dokument
umwandeln kann
XSL:
XSLT + Sammlung von Formatting Objects
Vorteile von XSL
XSL ist wesentlich leistungsfähiger als CSS.
Es ist möglich, unterschiedliche Layouts für ein Dokument zu erzeugen. Dazu benötigt man
nur ein anderes Stylesheet, die XML-Datei bleibt unverändert.
Das Layout von vielen Dateien mit gleichem
Stylesheet läßt sich einfacher und schneller
ändern als bei HTML-Dateien.
XSLT Stylesheet Processing
XML-Daten
(strukturell + semantisch)
XSLT Stylesheet
(Präsentation, optische Form)
Ausgabe XML HTML
PDF RTF ASCII
...
XML Prozessor
Apache XML Projekt
Quelle: http://xml.apache.org
Ziel: Entwicklung von W3C-Standard-
konformen XML-Lösungen auf kommerziellem Niveau in offener Zusammenarbeit
– Xerces XML Parser, in Java/C++
– Xalan XSL Stylesheet-Prozessor, in Java/C++
– Cocoon XML-based Web Publishing, in Java
– FOP XSL Formatting Objects, in Java
Xalan
Quelle: http://xml.apache.org/xalan/index.html
XSLT Prozessor für die Transformation von XML-Dokumenten in HTML, oder anderen XML-Dokumenttypen
Xalan-Java (Version2) ist eine komplette und stabile Implementation der W3-Empfehlung von XSLT und XPath
Benutzung z.B. über Kommandozeile, in einem Applet, oder als Modul in einem anderen
Programm
FOP (Formatting Object Processor)
Quelle: http://xml.apache.org/fop
Ziele:
– Entwicklung eines XSL FO=>PDF Formatierer
– Konform zur W3C-Empfehlung (21.11.2000)
– Berücksichtigung der PDF-Spezifikation (11.03.1999)
XSL Formatting Objects:
Programm zum Erzeugen von PDF / AWT / TXT / PRINT ... aus XML und XSL
Beispiel:
fop -xsl foo.xsl -xml foo.xml -pdf foo.pdf
XSL Formatting Model
<chapter>
<title>...</title>
<para>...
<emph>....</emph>
</para>
<para>...</para>
</chapter>
fo:block
fo:block fo:block fo:block
fo:inline
XML Source
Area Structure
FO Result Tree
XSLT
FO Result Tree
1.
<?xml version=“1.0“ encoding=“utf-8“?>
2.
<fo:root xmlns:fo=“http://www.w3.org/1999/XSL/Format“>
3.
...
4.
<fo:page-sequence>
5.
<fo:flow>
6.
<fo:block font-size=“18 pt“ font-weight=“bold“ text-align=“centered“
7.
Vorwort
8.
</fo:block>
9.
<fo:block font-size=“12 pt“ space-before=“1 pc“ text-aligned=“justified“>
10.
Dieses kleine Dokument zeigt einen FO Result Tree
11.
</fo:block>
12.
</fo:flow>
13.
</fo:page-sequence>
14.
...
15.
</fo:root>
Verarbeitung von XML mit XSLT
Zugriff auf alle Bestandteile des “XML- Baumes“
– Wurzel
– Elemente
– Text
– Attribute
– Namespaces
– Processing Instructions
– Kommentare
Wandeln des Dokumentenbaums mit Hilfe der
Vorgaben im Stylesheet in einen Zielbaum
Baumdiagramm XML => HTML
sample.xml => sample.html
<dokument>
<titel> <absatz>
<ueberschrift>
usw.
<HTML>
<HEAD> <P>
<H1>
<TITLE> usw.
XSLT Beispiele (1)
XSLT Befehle in W3-Spezifikation
viele Möglichkeiten zur Transformation:
–
Einfügen von Text
–
Sortieren
–
Numerieren
–
Bedingungsschleifen u.a.
Hinzufügen von Attributen
–
Hinzufügen eines Attributs zu einem Element im Ergebnisbaum, z.B.
<a>
<xsl:attribute name=“href“>
<xsl:value-of-select=“@url“/>
<xsl:attribute>
Homepage
</a>
Führt in HTML zu:
<a href=“...“>Homepage</a>
XSLT Beispiele (2)
Auswahl: eine Möglichkeit
<xsl:if test=“...“> ... </xsl:if>
Auswahl: mehrere Möglichkeiten
<xsl:choose>
<xsl:when test=“studium/@studium“>Text1</xsl:when>
<xsl:when test=“...“>Text2</xsl:when>
<xsl:otherwise>Text3</xsl:otherwise>
<xsl:choose>
Auswahl einer beliebigen Anzahl gleicher Elemente
<xsl:for-each select=“adresse“> ... </xsl:for-each>
–
Bestimmt eine Liste von SourceTree-Knoten zur Verarbeitung
–
Macht diese Liste von ausgewählten Knoten zur aktuellen Knotenliste
–
Beginnt Verarbeitung der Knoten in der Reihenfolge der aktuellen
Knotenliste
XSLT Beispiele (3)
Konstante
<xsl:constant name=“jahr“ value=“2001“/>
Automatische Numerierung der Elemente
<xsl:number level=“any“ from=“kapitel“ count=“absatz“/>
Sortierung der Elemente
<xsl:apply-templates select=“row“>
<xsl:sort data-type=“number“ select=“entry[2]“/>
</xsl:apply-templates>
Beispiel: ROWSET-Dokumentbaum
<!--Emp.xml -->
<ROWSET>
<ROW num=“1“>
<EMPNO>7839</EMPNO>
<ENAME>KING</ENAME>
</ROW>NEW YORK</LOC>
<ROW num=“2“>
<EMPNO>7788</EMPNO>
<ENAME>SCOTT</ENAME>
</ROW>
</ROWSET>
<!--Emp.xml -->
<ROWSET>
<ROW num=“1“>
<EMPNO>7839</EMPNO>
<ENAME>KING</ENAME>
</ROW>NEW YORK</LOC>
<ROW num=“2“>
<EMPNO>7788</EMPNO>
<ENAME>SCOTT</ENAME>
</ROW>
</ROWSET>
Templates
Templates = Regeln im Stylesheet
beinhalten Bauplan für Konstruktion eines Teils des Ergebnisbaums
<xsl:template match = “pattern“>
–
wählt ein bestimmtes Element aus, das über das Attribut match (XPath Pattern) näher spezifiziert wird
<xsl:template match=“/“>
<!-- Some Result Content: Elements, Attributes, Text, etc.-->
</xsl:template>
–
Regeln wird auf die Wurzel (Root Node) angewandt
Nutzung mehrerer Templates
<xsl:apply-templates>
–
Anweisung an den XSLT-Prozessor, mit den Kind-Knoten
Match Source - Construct Result
1. Einfügen von Literalen in den Result Tree, z.B. <Employee>
id
2. Bestimmung der Attributwerte der Form {XPathExpr} und Einsetzen in Result Tree 3. Verarbeitung aller Elemente
aus XSLT Namespace in
Dokumentenreihenfolge
mittels <xsl:value-of>
Single-Template Stylesheet
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<xsl:for-each select="ROWSET">
<table border="1" cellspacing="0">
<xsl:for-each select="ROW">
<tr>
<td><xsl:value-of select="EMPNO"/></td>
<td><xsl:value-of select="ENAME"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:for-each>
</body>
</html>
</xsl:template>
Verarbeitung
Ergebnis der Verarbeitung
<html>
<body>
<table border="1" cellspacing="0">
<tr>
<td>7839</td>
<td>KING</td>
</tr>
<tr>
<td>7788</td>
<td>SCOTT</td>
</tr>
</table>
</body>
</html>
<html>
<body>
<table border="1" cellspacing="0">
<tr>
<td>7839</td>
<td>KING</td>
</tr>
<tr>
<td>7788</td>
<td>SCOTT</td>
</tr>
</table>
</body>
</html>
Vereinfachtes Stylesheet
<html xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<body>
<xsl:for-each select="ROWSET">
<table border="1" cellspacing="0">
<xsl:for-each select="ROW">
<tr>
<td><xsl:value-of select="EMPNO"/></td>
<td><xsl:value-of select="ENAME"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:for-each>
</body>
</html>
Input- und Output-Optionen
Serialization
– Ausschreiben des Ergebnisbaums als Zeichenstrom
– Default Serialization Rules (in XSLT1.0 Spezifik.):
UTF-8 Character Set
<xsl:output> steuert Serialisierungsprozeß
Ausgabe-Methoden
– <xsl:output-method=“xml“/>
Default, Ausgabe als well-formed XML
– <xsl:output-method=“html“/>
Serialisiert Elemente und Attribute in HTML4.0-gemäßer Form für entsprechende Browser, kein well-formed XML!
– <xsl:output-method=“text“/>
XSLT Output Methoden
<xsl:output method = “xml“ indent=“yes“/>
<xsl:output method = “html“/>
<xsl:output method = “text“/>
Beispiel im Detail: Text-Output
Behandlung von Steuerzeichen
–
XSLT Stylesheets sind wohlgeformte XML-Dokumente
–
einige Zeichen benötigen Escape-Zeichen
& = & oder & (im Unicode)
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:text>Hello </xsl:text>
<xsl:value-of select="ROWSET/ROW/ENAME"/>
<xsl:text> & Family,
</xsl:text>
<xsl:text>Your id is </xsl:text>
<xsl:value-of select="ROWSET/ROW/EMPNO"/>
</xsl:template>
</xsl:stylesheet>
Hello King & Family,
Your id is 7839
Nutzung mehrerer Templates
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="no"/>
<xsl:template match="/">
<html>
<body><xsl:apply-templates/></body>
</html>
</xsl:template>
<xsl:template match="ROWSET">
<table border="1" cellspacing="0"><xsl:apply-templates/></table>
</xsl:template>
<xsl:template match="ROW">
<tr><xsl:apply-templates/></tr>
</xsl:template>
<xsl:template match="EMPNO">
<td><xsl:apply-templates/></td>
</xsl:template>
<xsl:template match="ENAME">
<td><xsl:apply-templates/></td>
</xsl:template>
</xsl:stylesheet>
mit mehreren Templates
• höhere Flexibilität
• bessere Wiederverwen- dung
• Analogie zu Java-Klassen
Built-In Templates
Teil jedes Stylesheets <xsl:template match="/|*">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text( )|@*">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="processing-instruction( )|comment( )"/>
Match Construct
Wurzelelement “/“ oder irgendein
Element “*“ Nichts, weiter mit Verarbeitung der Kind- Knoten des aktuellen Knotens
Textknoten „“text()“ oder Attribut “@*“ Textknoten mit dem Wert des aktuellen Knotens, Kopiere Text oder Attributwert in den Ergebnisbaum
Processing Instruction oder Kommentar Nichts
Anwendung von Wildcards
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!--
| EmpUsingRowStar.xsl:
| Transform Emp.xml Into <table> using ROW/* to handle any column +-->
<xsl:template match="/">
<html>
<body><xsl:apply-templates/></body>
</html>
</xsl:template>
<xsl:template match="ROWSET">
<table border="1" cellspacing="0"><xsl:apply-templates/></table>
</xsl:template>
<xsl:template match="ROW">
<tr><xsl:apply-templates/></tr>
</xsl:template>
<!-- Match any element child of a ROW -->
<xsl:template match="ROW/*">
Beispiel-Stylesheet mit mehreren Templates für ROWSET/ROW
Behandlung von Whitespaces
oraxsl Emp.xml EmpUsingRowStar.xsl erzeugt Ausgabe:
<html>
<body>
<table border="1" cellspacing="0">
<tr>
<td>7839</td>
<td>KING</td>
</tr>
<tr>
<td>7788</td>
<td>SCOTT</td>
</tr>
</table>
</body>
</html>
<html>
<body>
<table border="1" cellspacing="0">
<tr>
<td>7839</td>
<td>KING</td>
</tr>
<tr>
<td>7788</td>
<td>SCOTT</td>
</tr>
</table>
</body>
</html>
Ergänze Stylesheet: Ignoriere alle Elemente, die nur aus Leerzeichen bestehen
<xsl:strip-space element=“*“/>
Datenbankzugriff (XSQL + XSL)
<?xml version="1.0"?>
<!-- Emp.xsql -->
<xsql:query connection="xmlbook" xmlns:xsql="urn:oracle-xsql">
SELECT empno, ename, sal, deptno FROM emp
ORDER BY ename DESC
</xsql:query>
<?xml version="1.0"?>
<!-- EmpUsingRowStar.xsql -->
<?xml-stylesheet type="text/xsl" href="EmpUsingRowStar.xsl"?>
<!-- Include Emp.xsql and style it with EmpUsingRowStar.xsl -->
<xsql:include-xsql href="Emp.xsql" xmlns:xsql="urn:oracle-xsql"/>
Kombination von Emp.xsql mit EmpUsingRowStar.xsl ROW/* Template funktioniert für alle Spalten
Anwendung verschiedener Stylesheets möglich
Arbeit in verschiedenen Modi
Problemstellung: Anzeige des Tabellenkopfes in generischer Weise 2 Modi benötigt: Modus Column Headers vs. Regulärer Modus
<!-- Match any element child of a ROW when in "ColumnHeaders" Mode -->
<xsl:template match="ROW/*" mode="ColumnHeaders">
<th>
<!-- Put the value of the *name* of the current element -->
<xsl:value-of select="name(.)"/>
</th>
</xsl:template>
<!-- Apply templates to children of current node in "ColumnHeader" mode -->
<xsl:apply-templates mode="ColumnHeaders"/>
<xsl:template match="ROWSET">
<table border="1" cellspacing="0">
<!-- Apply templates in "ColumnHeader" mode first -->
<xsl:apply-templates mode="ColumnHeaders"/>
<!-- Then apply templates to all child nodes normally -->
<xsl:apply-templates/>
</table>
</xsl:template>
ROWSET HTML Tabelle
| TableBaseWithCSS:
| Basic stylesheet to format any ROWSET of ROWS into a table | with column headings in a generic way. Leverages Table.css | CSS stylesheet to control font/color information for the page.
+-->
<xsl:template match="/">
<html>
<!-- Generated HTML result will be linked to Table.css CSS stylesheet -->
<head><link rel="stylesheet" type="text/css" href="Table.css"/></head>
<body><xsl:apply-templates/></body>
</html>
</xsl:template>
<xsl:template match="ROWSET">
<table border="1" cellspacing="0">
<!-- Apply templates in "ColumnHeader" mode to just *first* ROW child -->
<xsl:apply-templates select="ROW[1]/*" mode="ColumnHeaders"/>
<!-- Then apply templates to all child nodes normally -->
<xsl:apply-templates/>
</table>
</xsl:template>
<xsl:template match="ROW">
<tr><xsl:apply-templates/></tr>
</xsl:template>
<!-- Match any element child of a ROW -->
<xsl:template match="ROW/*">
<td><xsl:apply-templates/></td>
</xsl:template>
<!-- Match any element child of a ROW when in "ColumnHeaders" Mode-->
<xsl:template match="ROW/*" mode="ColumnHeaders">
<th>
Stylesheets
Importieren eines Base Stylesheet und Hinzufügen eines neuen Templates Neues Stylesheet EmpOver2000.xsl:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Import all the templates from "TableBaseWithCSS.xsl" as a base -->
<xsl:import href="TableBaseWithCSS.xsl"/>
<!-- Override imported template for ROW to match ROWs with a SAL>2000 -->
<xsl:template match="ROW[ SAL > 2000 ]">
<tr class="Highlight"><xsl:apply-templates/></tr>
</xsl:template>
</xsl:stylesheet>
Erweitere Table.css, z.B. .Highlight {background-color: e7e7e7e } Verwende Emp.sql und transformiere entsprechend EmpOver2000.xsl
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="EmpOver2000.xsl"?>
<xsql:include-xsql href="Emp.xsql" xmlns:xsql="urn:oracle-xsql"/>
von Stylesheets (Forts.)
Ergebnis von EmpOver2000.xsl:
Hervorhebung aller Angestellten in Tabelle mit Gehalt > 2000
Weitere Beispiele:
• Formatiere gerade Zeilen in einer Farbe
• Formatiere ungerade Zeilen in einer anderen Farbe
• Formatiere Zeilen aus Dept 20 durch Ausgabe von “Classified“
Mehr Informationen:
Siehe S. Muench “Building Oracle XML Applications“, Verlag O‘Reilly, 2000
(Kapitel 7).
Prioritäten zur Konfliktvermeidung
Basis-Schema für Auswahl von Templates
*
SOMETHING oder xyz:SOMETHING
SOMETHING[predicate] oder SOMETHING/SOMETHINGELSE
Problem bei mehrfachen Pattern auf derselben Stufe
–
Einführung eines priority=“realnumber“ Attributes im Template
–
Auswahl des Templates mit höchster Priorität durch Prozessor Beispiel-Anwendung:
Abwechselndes Hervorheben von Tabellenzeilen vs.
Ausblenden von Zeilen aus DEPT = 20
Template für DEPT=20 hat höhere Priorität
Reusable Named Templates
Idee: Alternative zu Pattern-Matching-Templates
Beispiel:
Formatieren von Tabellenzellen mit numerischen Werten, z.B.
Anzeige mit Dollar und Cent
<!-- "Utility" template to format money is a common way -->
<xsl:template name="moneyCell">
<td align="right"><xsl:value-of select="format-number(.,'$0.00')"/></td>
</xsl:template>
Aufruf:
–
muß explizit erfolgen mittels <xsl:call-template>
–
Literale und xsl Actions genauso instanziiert als ob sie im
aufrufenden Template eingefügt wären aufgerufenes
Template sieht gleichen aktuellen Knoten wie rufendes
Library Stylesheets
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Handle even/odd formatting of rows using CSS classes "tr0"
and "tr1" -->
<xsl:template match="ROW">
<tr class="tr{position( ) mod 2}"><xsl:apply-templates/></tr>
</xsl:template>
<!-- "Utility" template to format money is a common way -->
<xsl:template name="moneyCell">
<td align="right"><xsl:value-of select="format-number(.,'$0.00')"/></td>
</xsl:template>
</xsl:stylesheet>
Einfügen von Named Templates in “Library“ Stylesheet: CommonLibrary.xsl
<xsl:stylesheet version="1.0„
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="TableBaseWithCSS.xsl"/>
<xsl:import href="CommonLibrary.xsl"/>
<xsl:template match="ROW/SAL">
<xsl:call-template name="moneyCell"/>
</xsl:template>