<?xml version="1.0"?>

<!-- ==========================================================================
 Project:     Notes for XML Course, August 2000, University of Giessen
 Author:      Stefan Brass
 Email:       sbrass@sis.pitt.edu
 Last Change: August 24, 2000
 Module:      c7_xslt.xml
 Purpose:     Chapter 7: XML Path Language (XPath)
=========================================================================== -->

<!DOCTYPE COURSENOTES SYSTEM "notes.dtd">

<?xml-stylesheet type="text/xsl" href="notes.xsl"?>

<COURSENOTES DATE='24. August 2000' FILE='c7_xslt.xml'>

<CHAPTER>
<TITLE>XSL Transformations (XSLT)</TITLE>

<SECTION>
<H>Motivation</H>
<LIST>
<I>XML selbst ist nur ein Datenformat:
	Es macht keine Angaben dar<ue/>ber,
	wie die einzelnen Elemente auszudrucken sind.
	Das Ausgabe-Format wird in sogenannten Stylesheets festgelegt.</I>
<I>Der Internet-Explorer unterst<ue/>tzt auch die von HTML her bekannten
	``Cascading Stylesheets'' (CSS) f<ue/>r XML.</I>
<I>Wesentlich m<ae/>chtiger ist jedoch XSL,
	die Extensible Stylesheet Language.
	Zum Beispiel erlaubt es XSL,
	Elemente in der Eingabe umzusortieren oder zu filtern.
	Mit CSS werden alle Elemente in der Reihenfolge formatiert,
	in der sie aufgeschrieben sind.</I>
<I>XSL besteht aus zwei Teilen:
	Einerseits XSLT,
	das ist ein Mechanismus zur Transformation
	von XML Dokumenten in XML Dokumente (mit z.B.<n/>anderen Tags),
	und andererseits den ``Formatting Objects'',
	das ist ein Satz von Tags
	mit einer vorgegebenen Semantik f<ue/>r die Ausgabe.</I>
<I>W<ae/>hrend XSLT<n/>1.0 seit dem 16.<n/>November 1999
	eine W3C Recommendation ist
	(also ein offiziell verabschiedeter Standard)
	<URL>http://www.w3.org/TR/xslt</URL>,
	sind die ``Formatting Objects'' immer noch ein Working Draft
	<URL>http://www.w3.org/TR/xsl/</URL>
	(zuletzt ge<ae/>ndert am 27.<n/>M<ae/>rz 2000).</I>
<I>Daher wird XSLT heute meist benutzt,
	um XML in HTML umzuwandeln,
	was dann in einem Browser angezeigt werden kann.
	Diese Umwandlung ist ohnehin wichtig,
	weil nicht alle Browser bereits XML verstehen.
	<NOTE>Wenn man heute im Web XML Dateien anbietet,
	und sich nicht nur an bekannte Gesch<ae/>ftskunden wendet,
	wird man wohl alternativ auch das Ergebnis der Umwandlung
	nach HTML anbieten m<ue/>ssen.
	Es ist aber auch m<oe/>glich,
	da<ss/> der Web-Server die Umwandlung bei Bedarf automatisch
	durchf<ue/>hrt.
	Der Browser schickt im Request ja auch die Information,
	welche Datenformate er versteht.</NOTE></I>
</LIST>
</SECTION>

<SECTION>
<H>Erstes Beispiel</H>
<LIST>
<I>Sei als Beispiel wieder die Buchliste verwendet:
	<CODE>
	<L><XDECL>version="1.0"</XDECL></L>
	<L><PI>xml-stylesheet type=<QUOT/>text/xsl<QUOT/>
		href=<QUOT/>books<U/>ie.xsl<QUOT/></PI></L>
	<L><BEG>BOOKLIST</BEG></L>
	<L><T/><BEG>BOOK ISBN=<QUOT/>0-13-014714-1<QUOT/>
			PAGES=<QUOT/>1074<QUOT/></BEG></L>
	<L><T/><T/><EMPTY>AUTHOR FIRST=<QUOT/>Paul<QUOT/>
			LAST=<QUOT/>Prescod<QUOT/></EMPTY></L>
	<L><T/><T/><EMPTY>AUTHOR FIRST=<QUOT/>Charles<QUOT/>
			MI=<QUOT/>F.<QUOT/>
			LAST=<QUOT/>Goldfarb<QUOT/></EMPTY></L>
	<L><T/><T/><BEG>TITLE</BEG>XML:
		The XML Handbook - 2nd Edition<END>TITLE</END></L>
	<L><T/><T/><BEG>PUBLISHER DATE=<QUOT/>19991112<QUOT/></BEG
			>Prentice Hall<END>PUBLISHER</END></L>
	<L><T/><T/><BEG>NOTE</BEG>Contains CD.<END>TITLE</END></L>
	<L><T/><END>BOOK</END></L>
	<L><T/><BEG>BOOK ISBN=<QUOT/>1-56592-709-5<QUOT/>
			PAGES=<QUOT/>107<QUOT/></BEG></L>
	<L><T/><T/><EMPTY>AUTHOR FIRST=<QUOT/>Robert<QUOT/>
			LAST=<QUOT/>Eckstein<QUOT/></EMPTY></L>
	<L><T/><T/><BEG>TITLE</BEG>XML Pocket Reference<END>TITLE</END></L>
	<L><T/><T/><BEG>PUBLISHER DATE=<QUOT/>19991001<QUOT/></BEG
			>O'Reilly<END>PUBLISHER</END></L>
	<L><T/><END>BOOK</END></L>
	<L><END>BOOKLIST</END></L>
	</CODE>
	Eine etwas erweiterte Version dieser Datei steht unter der URL
<URL>http://www.informatik.uni-giessen.de/staff/brass/xml00/booklist.xml</URL
	>.</I>
<I>Man kann nun zum Beispiel folgendes Stylesheet zum Ausdrucken verwenden
<URL>http://www.informatik.uni-giessen.de/staff/brass/xml00/book1_ie.xsl</URL
	>:
	<CODE>
	<L><XDECL>version=<QUOT/>1.0<QUOT/></XDECL></L>
	<L><BEG>xsl:stylesheet
		xmlns:xsl=<QUOT/>http://www.w3.org/TR/WD-xsl<QUOT/>
		version=<QUOT/>1.0<QUOT/></BEG></L>
	<L><BEG>xsl:template match=<QUOT/>/<QUOT/></BEG></L>
	<L><T/><BEG>HTML</BEG></L>
	<L><T/><BEG>HEAD</BEG><BEG>TITLE</BEG>Books About XML<END>TITLE</END
		><END>HEAD</END></L>
	<L><T/><BEG>BODY</BEG></L>
	<L><T/><BEG>UL</BEG></L>
	<L><T/><T/><EMPTY>xsl:apply-templates
			select=<QUOT/>/BOOKLIST/BOOK<QUOT/></EMPTY></L>
	<L><T/><END>UL</END></L>
	<L><T/><END>BODY</END></L>
	<L><T/><END>HTML</END></L>
	<L><END>xsl:template</END></L>
	<L><BEG>xsl:template match=<QUOT/>BOOK<QUOT/></BEG></L>
	<L><T/><BEG>LI</BEG><EMPTY>xsl:apply-templates
			select=<QUOT/>AUTHOR[0]<QUOT/></EMPTY
			>:<EMPTY>BR</EMPTY></L>
	<L><T/><T/><BEG>EM</BEG><EMPTY>xsl:apply-templates
			select=<QUOT/>TITLE<QUOT/></EMPTY
			>.<END>EM</END><EMPTY>BR</EMPTY></L>
	<L><T/><T/><EMPTY>xsl:apply-templates
			select=<QUOT/>PUBLISHER<QUOT/></EMPTY><END>LI</END></L>
	<L><END>xsl:template</END></L>
	<L><BEG>xsl:template match=<QUOT/>AUTHOR<QUOT/></BEG></L>
	<L><T/><EMPTY>xsl:value-of select=<QUOT/>@LAST<QUOT/></EMPTY>,</L>
	<L><T/><EMPTY>xsl:value-of select=<QUOT/>@FIRST<QUOT/></EMPTY></L>
	<L><END>xsl:template</END></L>
	<L><BEG>xsl:template match=<QUOT/>TITLE<QUOT/></BEG></L>
	<L><T/><EMPTY>xsl:value-of select=<QUOT/>.<QUOT/></EMPTY></L>
	<L><END>xsl:template</END></L>
	<L><BEG>xsl:template match=<QUOT/>PUBLISHER<QUOT/></BEG></L>
	<L><T/><EMPTY>xsl:value-of select=<QUOT/>.<QUOT/></EMPTY></L>
	<L><END>xsl:template</END></L>
	<L><END>xsl:stylesheet</END></L>
	</CODE>
	Aus didaktischen Gr<ue/>nden wird hier nur der erste Autor
	ausgegeben,
	sowie auch die optionale Anmerkung unterdr<ue/>ckt.
	Unten gibt es eine komplexere Version,
	die auch diese Probleme l<oe/>st.</I>
<I>Wie man an diesem Beispiel sieht,
	besteht ein Stylesheet im wesentlichen
	aus einer Menge von ``Templates''
	(Mustern, Transformations-Regeln).</I>
<I>Jedes dieser Muster beschreibt eine Transformation
	von einem Teilbaum der Eingabe
	(d.h.<n/>einem aktuellen Startknoten und allen seinen Nachfolgern)
	in einen Baum oder eine Liste von B<ae/>umen.</I>
<I>Die Ausgabe der Transformation f<ue/>r ein gegebenes XML-Dokument
	wird durch die Regel f<ue/>r den Wurzel-Knoten
	(d.h.<n/>den gesamten Eingabe-Baum) bestimmt.
	Alle anderen Regeln werden nur aktiv,
	wenn sie von dem Muster f<ue/>r ``<ICODE>/</ICODE>''
	mit ``<ICODE>apply-templates</ICODE>'' aufgerufen werden.</I>
<I>Jede Transformations-Regel (``Template'')
	besteht also im wesentliche aus zwei Teilen:
	Das Attribut ``<ICODE>match</ICODE>'' legt fest,
	f<ue/>r welche Knoten diese Transformations-Regel gilt.
	Der Inhalt von ``<ICODE>xsl:template</ICODE>''
	ist ein Muster f<ue/>r die Ausgabe:
	Dort stehende HTML-Tags und Text
	werden unver<ae/>ndert in die Ausgabe kopiert.
	Im Muster stehende XSL-Tags werden dagegen ausgewertet.
	Im Beispiel kommen nur zwei solche Tags vor:
	``<ICODE>xsl:apply-templates</ICODE>''
	und ``<ICODE>xsl:value-of</ICODE>''.</I>
<I>``<ICODE>xsl:apply-templates</ICODE>'' wird ersetzt
	durch das Ergebnis eines rekursiven Aufrufs
	der Transformation f<ue/>r den im ``<ICODE>select</ICODE>''-Attribut
	spezifizierten Knoten.
	Der Inhalt dieses Attributes ist ein XPath-Pfadausdruck.
	Nat<ue/>rlich k<oe/>nnen auf diese Art
	mehrere Knoten selektiert sein.
	Dann werden die Transformations-Ergebnisse
	entsprechend der Reihenfolge dieser Knoten
	im Eingabebaum hintereinander in den Ausgabebaum eingef<ue/>gt.
	Das Attribut ``<ICODE>select</ICODE>'' kann weggelassen werden.
	In diesem Fall werden einfach alle Kind-Knoten
	transformiert (Element-Knoten, Text-Knoten, etc.).</I>
<I>``<ICODE>xsl:value-of</ICODE>'' wird ersetzt durch den Wert des Knotens,
	der im ``<ICODE>select</ICODE>''-Attribut ausgew<ae/>hlt ist.
	Werte von Knoten wurden im Datenmodell im Kapitel <ue/>ber XPath
	definiert.
	Sie sind im wesentlichen der Text-Inhalt.
	Das Attribut ``<ICODE>xsl:value-of</ICODE>'' kann nicht
	weggelassen werden (beim Internet Explorer schon),
	aber wie von XPath bekannt,
	kann man den Knoten selbst mit ``<ICODE>.</ICODE>'' ansprechen.
	So wurden oben die Elemente ``<ICODE>TITLE</ICODE>''
	und ``<ICODE>PUBLISHER</ICODE>''
	einfach durch ihren Text-Inhalt ersetzt.</I>
<I>Man kann sich nun wundern,
	warum das Attribut einmal ``<ICODE>match</ICODE>''
	und einmal ``<ICODE>select</ICODE>'' hei<ss/>t,
	obwohl beide im wesentlichen XPath-Ausdr<ue/>cke enthalten
	(allerdings mit unterschiedlichen Einschr<ae/>nkungen).
	Der Grund ist,
	da<ss/> die Semantik des ``<ICODE>match</ICODE>''-Ausdruckes
	etwas anders ist:
	Eine Transformationsregel ist auf einen Knoten<n/><M>X</M>
	anwendbar,
	wenn es einen Knoten<n/><M>Y</M> gibt,
	der ein Vorg<ae/>nger von<n/><M>X</M> ist
	(oder gleich<n/><M>X</M>),
	so da<ss/> der ``<ICODE>match</ICODE>''-Ausdruck
	mit Startknoten<n/><M>Y</M>
	den Knoten<n/><M>X</M> ausw<ae/>hlt (plus eventuell weitere Knoten).
	Zum Beispiel passt das Muster ``<ICODE>BOOK/TITLE</ICODE>''
	auf einen ``<ICODE>TITLE</ICODE>''-Knoten,
	dessen Vater ein ``<ICODE>BOOK</ICODE>-Knoten ist
	(und nicht etwa auf einen <ICODE>BOOK</ICODE>-Knoten,
	der einen <ICODE>TITLE</ICODE>-Knoten
	als Kind hat).</I>
<I>Man beachte,
	da<ss/> die HTML-Tags hier in XML verwendet werden.
	Sie m<ue/>ssen also wohlgeformtes XML sein.
	Zum Beispiel kann man in HTML einfach ``<ICODE><BEG>BR</BEG></ICODE>''
	schreiben,
	aber hier mu<ss/> man jedes ge<oe/>ffnete Tag auch wieder schlie<ss/>en,
	was am einfachsten mit ``<ICODE><EMPTY>BR</EMPTY></ICODE>'' geht.
	Entsprechend sind auch die ``<ICODE><END>LI</END></ICODE>''-Tags
	n<oe/>tig,
	die man in reinem HTML eher selten sieht
	(sie werden in XHTML aber verlangt werden).
	Schlie<ss/>lich hat XML nur die f<ue/>nf vordefinierten Entities
	<ICODE>lt</ICODE>,
	<ICODE>gt</ICODE>,
	<ICODE>amp</ICODE>,
	<ICODE>quot</ICODE>,
	<ICODE>apos</ICODE>.
	Will man also z.B.<n/>``<ICODE><EREF>auml</EREF></ICODE>'' verwenden,
	um ein ``<ae/>'' auszugeben,
	so mu<ss/> man dieses Entity deklarieren.
	Dies geschieht zum Beispiel so:
	<CODE>
	<L><LT/>!DOCTYPE stylesheet_umlaute [</L>
        <L><T/><EDECL>Auml <QUOT/><CREF>x00C4</CREF><QUOT/></EDECL></L>
        <L><T/><EDECL>auml <QUOT/><CREF>x00E4</CREF><QUOT/></EDECL></L>
        <L><T/><EDECL>Ouml <QUOT/><CREF>x00D6</CREF><QUOT/></EDECL></L>
        <L><T/><EDECL>ouml <QUOT/><CREF>x00F6</CREF><QUOT/></EDECL></L>
        <L><T/><EDECL>Uuml <QUOT/><CREF>x00DC</CREF><QUOT/></EDECL></L>
        <L><T/><EDECL>uuml <QUOT/><CREF>x00FC</CREF><QUOT/></EDECL></L>
        <L><T/><EDECL>szlig <QUOT/><CREF>x00DF</CREF><QUOT/></EDECL></L>
        <L><T/><EDECL>nbsp <QUOT/><CREF>x00A0</CREF><QUOT/></EDECL></L>
	<L>]<GT/></L>
	</CODE>
	Die Zahlenwerte kann man aus der HTML-DTD oder dem Unicode-Standard
	entnehmen.</I>
<I>Aufgabe: Modifizieren Sie das Stylesheet so,
	da<ss/> zun<ae/>chst der Titel ausgegeben wird,
	und dann in der n<ae/>chsten Zeile
	nach dem Wort ``<ICODE>by</ICODE>''
	der Name des (ersten) Autors,
	diesmal aber zuerst der Vorname und dann der Nachname.
	Der Verlag soll weggelassen werden.
	Beachten Sie,
	wie einfach es ist,
	Daten aus der Eingabe umzuordnen oder wegzulassen.</I>
</LIST>
</SECTION>

<SECTION>
<H>Zweites Beispiel</H>
<LIST>
<I>Das folgende Stylesheet druckt die gesamte Liste
	der Autoren aus, durch ``<ICODE>/</ICODE>'' getrennt.
<URL>http://www.informatik.uni-giessen.de/staff/brass/xml00/book2_ie.xsl</URL
	>:
	<CODE>
	<L><XDECL>version=<QUOT/>1.0<QUOT/></XDECL></L>
	<L><BEG>xsl:stylesheet
		xmlns:xsl=<QUOT/>http://www.w3.org/TR/WD-xsl<QUOT/>
		version=<QUOT/>1.0<QUOT/></BEG></L>
	<L><BEG>xsl:template match=<QUOT/>/<QUOT/></BEG></L>
	<L><T/><BEG>HTML</BEG></L>
	<L><T/><BEG>HEAD</BEG><BEG>TITLE</BEG>Books About XML<END>TITLE</END
		><END>HEAD</END></L>
	<L><T/><BEG>BODY</BEG></L>
	<L><T/><BEG>UL</BEG></L>
	<L><T/><T/><EMPTY>xsl:apply-templates
			select=<QUOT/>/BOOKLIST/BOOK<QUOT/></EMPTY></L>
	<L><T/><END>UL</END></L>
	<L><T/><END>BODY</END></L>
	<L><T/><END>HTML</END></L>
	<L><END>xsl:template</END></L>
	<L><BEG>xsl:template match=<QUOT/>BOOK<QUOT/></BEG></L>
	<L><T/><BEG>LI</BEG><EMPTY>xsl:apply-templates
			select=<QUOT/>AUTHOR<QUOT/></EMPTY
			>:<EMPTY>BR</EMPTY></L>
	<L><T/><T/><BEG>EM</BEG><EMPTY>xsl:apply-templates
			select=<QUOT/>TITLE<QUOT/></EMPTY
			>.<END>EM</END><EMPTY>BR</EMPTY></L>
	<L><T/><T/><EMPTY>xsl:apply-templates
			select=<QUOT/>PUBLISHER<QUOT/></EMPTY><END>LI</END></L>
	<L><END>xsl:template</END></L>
	<L><BEG>xsl:template match=<QUOT/>AUTHOR<QUOT/></BEG></L>
	<L><T/><EMPTY>xsl:value-of select=<QUOT/>@LAST<QUOT/></EMPTY>,</L>
	<L><T/><EMPTY>xsl:value-of select=<QUOT/>@FIRST<QUOT/></EMPTY> /</L>
	<L><END>xsl:template</END></L>
	<L><BEG>xsl:template match=<QUOT/>AUTHOR[end()]<QUOT/></BEG></L>
	<L><T/><EMPTY>xsl:value-of select=<QUOT/>@LAST<QUOT/></EMPTY>,</L>
	<L><T/><EMPTY>xsl:value-of select=<QUOT/>@FIRST<QUOT/></EMPTY></L>
	<L><END>xsl:template</END></L>
	<L><BEG>xsl:template match=<QUOT/>TITLE<QUOT/></BEG></L>
	<L><T/><EMPTY>xsl:value-of select=<QUOT/>.<QUOT/></EMPTY></L>
	<L><END>xsl:template</END></L>
	<L><BEG>xsl:template match=<QUOT/>PUBLISHER<QUOT/></BEG></L>
	<L><T/><EMPTY>xsl:value-of select=<QUOT/>.<QUOT/></EMPTY></L>
	<L><END>xsl:template</END></L>
	<L><END>xsl:stylesheet</END></L>
	</CODE></I>
<I>In der Regel f<ue/>r das Element ``<ICODE>BOOK</ICODE>''
	wird die Transformation nun rekursiv f<ue/>r alle Autoren
	verlangt.
	Die Transformations-Ergebnisse werden dann
	entsprechend der Dokument-Reihenfolge der <ICODE>AUTHOR</ICODE>-Knoten
	in den Ergebnis-Baum eingebaut.</I>
<I>Es gibt nun zwei Transformations-Regeln,
	die sich auf Autoren beziehen:
	Das Muster in der ersten Regel
	passt auf beliebige <ICODE>AUTHOR</ICODE>-Knoten,
	das Muster in der zweiten Regel nur auf den letzten
	<ICODE>AUTHOR</ICODE>-Knoten des jeweiligen Vater-Knotens
	(siehe die Erkl<ae/>rung zu ``<ICODE>match</ICODE>'' oben).</I>
<I>Der XSLT-Standard erkl<ae/>rt in Abschnitt<n/>5.5
	<URL>ttp://www.w3.org/TR/xslt#conflict</URL>
	wie die anzuwendene Regel ausgew<ae/>hlt wird,
	wenn die Muster von mehreren Regeln passen.
	Die Priorit<ae/>t f<ue/>r einfache Namen ist<n/><ICODE>0</ICODE>
	(dies gilt f<ue/>r die erste Autor-Regel),
	w<ae/>hrend die Priorit<ae/>t f<ue/>r komplexere Muster<n/><ICODE>0.5</ICODE>
	ist
	(dies trifft auf die zweite Autor-Regel zu).
	Daher wird f<ue/>r den jeweils letzten Autor-Knoten
	die speziellere zweite Regel verwendet.
	Im Internet Explorer scheint es aber so,
	als w<ue/>rde immer die jeweils letzte passende Regel angewendet.
	Dort ist es also wichtig,
	die Regeln in dieser Reihenfolge aufzuschreiben.</I>
</LIST>
</SECTION>

<SECTION>
<H>Drittes Beispiel</H>
<LIST>
<I>Nehmen wir an,
	wir haben ein wirkliches ``mixed content model'',
	also zum Beispiel einen Text,
	der auch URLs und betonte Text-Teile enthalten kann:
	<CODE>
	<L><XDECL>version="1.0"</XDECL></L>
	<L><PI>xml-stylesheet type=<QUOT/>text/xsl<QUOT/>
		href=<QUOT/>email<U/>ie.xsl<QUOT/></PI></L>
	<L><BEG>EMAIL</BEG></L>
	<L><T/><BEG>FROM</BEG>sbrass@sis.pitt.edu<END>FROM</END></L>
	<L><T/><BEG>TO</BEG>stefan.brass@informatik.uni-giessen.de<END>TO</END
			></L>
	<L><T/><BEG>CONTENTS</BEG>Die
		<BEG>EMPH</BEG>XSLT-Spezifikation<END>EMPH</END></L>
	<L><T/><T/>steht unter
		<BEG>URL</BEG>http://www.w3.org/TR/xslt<END>URL</END>.</L>
	<L><T/><END>CONTENTS</END></L>
	<L><END>EMAIL</END></L>
	</CODE></I>
<I>Die Transformationsregeln f<ue/>r den Inhalt sind nun
	(der Rest des Stylesheets sei als <UE/>bungsaufgabe gestellt):
	<CODE>
	<L><BEG>xsl:template match=<QUOT/>CONTENTS<QUOT/></BEG></L>
	<L><T/><BEG>P</BEG><EMPTY>xsl:apply-templates</EMPTY><END>P</END></L>
	<L><END>xsl:template</END></L>
	<L><BEG>xsl:template match=<QUOT/>EMPH<QUOT/></BEG><BEG>EM</BEG
		><EMPTY>xsl:apply-templates</EMPTY><END>EM</END
		><END>xsl:template</END></L>
	<L><BEG>xsl:template match=<QUOT/>URL<QUOT/></BEG><LT/>A</L>
	<L><T/><GT/><EMPTY>xsl:attribute name=<QUOT/>HREF<QUOT/></EMPTY><EMPTY
		>xsl:value-of select=<QUOT/>.<QUOT/></EMPTY><LT
		/>xsl-attribute</L>
	<L><T/><GT/><EMPTY>xsl:apply-templates</EMPTY><END>A</END><END
		>xsl:template</END></L>
	<L><BEG>xsl:template match=<QUOT/>text()<QUOT/></BEG><BEG>EM</BEG
		><EMPTY>xsl:value-of select=<QUOT/>.<QUOT/></EMPTY><END>EM</END
		><END>xsl:template</END></L>
	</CODE></I>
</LIST>
</SECTION>

</CHAPTER>
</COURSENOTES>

