<?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 22, 2000
 Module:      c6_xpath.xml
 Purpose:     Chapter 6: XML Path Language (XPath)
=========================================================================== -->

<!DOCTYPE COURSENOTES SYSTEM "notes.dtd">

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

<COURSENOTES DATE='22. August 2000' FILE='c6_xpath.xml'>

<CHAPTER>
<TITLE>XML Path Language (XPath)</TITLE>

<SECTION>
<H>Motivation</H>
<LIST>
<I>XPath ist ein Standard f<ue/>r Ausdr<ue/>cke,
	die der Auswahl von Teilen von XML-Dokumenten dienen.</I>
<I>XPath wird z.B.<n/>in XSLT (XML Stylesheet Language - Transformations)
	verwendet,
	um f<ue/>r jede Transformations-Regel zu beschreiben,
	auf welche Elemente sie sich bezieht,
	un welche Sub-Elemente weiter verarbeitet werden sollen.</I>
<I>XPath wird auch in XPointer verwendet,
	um einen beliebigen Teil eines Argumentes
	adressierbar zu machen
	(etwa f<ue/>r Hyperlinks).</I>
<I>XPath kann auch als einfache Anfragesprache f<ue/>r XML-Datenbanken
	verstanden werden.
	Zuk<ue/>nftige Vorschl<ae/>ge f<ue/>r XML-Anfragesprachen
	werden sich an XPath messen lassen m<ue/>ssen.</I>
<I>Ausdr<ue/>cke/Anfragen in XPath haben eine Form,
	die <ae/>hnlich zu Pfadausdr<ue/>cken im UNIX-Dateisystem ist,
	daher der Name.
	Zum Beispiel selektiert
	<CODE>
	<L>/BOOKLIST/BOOK/TITLE</L>
	</CODE>
	alle <ICODE>TITLE</ICODE>-Elemente,
	die Kinder von <ICODE>BOOK</ICODE>-Elementen sind,
	die wiederum Kinder des <ICODE>BOOKLIST</ICODE> Wurzel-Elementes
	sind.</I>
<I>Die XML Path Language (XPath), Version<n/>1.0,
	ist seit dem 16.<n/>November 1999 eine W3C Recommendation
	<URL>http://www.w3.org/TR/xpath</URL>.</I>
</LIST>
</SECTION>

<SECTION>
<H>Anleitung zum Experimentieren mit XPath-Ausdr<ue/>cken</H>
<LIST>
<I>Zum Beispiel k<oe/>nnte man die Anfrage
	``<ICODE>/BOOKLIST/BOOK/TITLE</ICODE>'' in folgendem
	Stylesheet f<ue/>r den Internet Explorer verwenden:
	<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>Query Result<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/TITLE<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/>@*|node()<QUOT/></BEG></L>
	<L><T/><BEG>LI</BEG><EMPTY>xsl:value-of
			select=<QUOT/>.<QUOT/></EMPTY><END>LI</END></L>
	<L><END>xsl:template</END></L>
	<L><END>xsl:stylesheet</END></L>
	</CODE>
	Stylesheets werden erst im n<ae/>chsten Kapitel erl<ae/>utert,
	aber man kann in diese Datei
	als Wert des ``<ICODE>select</ICODE>''-Attributes
	von ``<ICODE>xsl:apply-templates</ICODE>''
	XPath-Ausdr<ue/>cke einsetzen,
	um mit XPath zu experimentieren.
	Die Datei steht im Web unter der URL
<URL>http://www.informatik.uni-giessen.de/staff/brass/xml00/query_ie.xsl</URL
	>.
	Eine Variante f<ue/>r Apache Xalan steht unter
<URL>http://www.informatik.uni-giessen.de/staff/brass/xml00/query_xa.xsl</URL
	>.
	Eine dritte Variante,
	die das Anfrage-Ergebnis als XML ausgibt
	(funktioniert nicht mit Internet Explorer),
	steht unter
<URL>http://www.informatik.uni-giessen.de/staff/brass/xml00/query_xm.xsl</URL
	>.
	</I>
<I>In der Buchliste verweist man dann auf dieses Stylesheet:
	<CODE>
	<L><XDECL>version="1.0"</XDECL></L>
	<L><PI>xml-stylesheet type=<QUOT/>text/xsl<QUOT/>
		href=<QUOT/>query<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 Datei mit Daten von diesen und anderen B<ue/>chern steht im Web
	unter der URL
<URL>http://www.informatik.uni-giessen.de/staff/brass/xml00/books.xsl</URL
	>.</I>
<I>Schaut man sich die Datei im Internet Explorer an,
	so bekommt man wie erwartet die Titel der B<ue/>cher in der Datei
	als HTML ``Unordered List'' angezeigt.
	Bei Bedarf kann man das Ausgabeformat im Stylesheet <ae/>ndern.</I>
</LIST>
</SECTION>

<SECTION>
<H>Datenmodell</H>
<LIST>
<I>Um XPath zu verstehen,
	mu<ss/> man sich das Eingabe-Dokument als Baum vorstellen,
	wie wir das schon in Kapitel<n/>2 ``Well-Formed XML'' getan haben.</I>
<I>Im Unterschied zur Illustration in Kapitel<n/>2
	gibt es hier aber einen Wurzel-Knoten,
	der noch oberhalb des Wurzel-Elementes (oder Dokument-Elementes)
	steht.
	Ein XML-Dokument kann vor dem Start-Tag des Dokument-Elementes
	und nach seinem End-Tag noch Kommentare und Processing-Instructions
	enthalten.
	Diese sind im Baum auch repr<ae/>sentiert
	(als Kinder des Wurzel-Knotens).
	Das Dokument-Element ist ebenfalls Kind des Wurzel-Knotens.</I>
<I>Insgesamt unterscheidet das XPath Datenmodell
	sieben verschiedene Typen von Knoten:
	Wurzel-Knoten,
	Element-Knoten,
	Text-Knoten,
	Attribut-Knoten,
	Namespace-Knoten,
	Kommentar-Knoten,
	und Knoten f<ue/>r Processing-Instructions.
	Naturgem<ae/><ss/> kann ein Knoten vom Typ Wurzel-Knoten
	in jedem Baum nur einmal vorkommen,
	und zwar als Wurzel.</I>
<I>Man beachte,
	da<ss/> es keine Entity-Knoten gibt.
	Der Baum wird aufgebaut,
	nachdem die Entities ersetzt sind.
	In den Text-Knoten tauchen keine Entity-Referenzen mehr auf,
	und auch CDATA-Abschnitte im Text werden
	nicht explizit repr<ae/>sentiert:
	Sie sind nur ein Mittel,
	um bestimmte Zeichen leicher eingeben zu k<oe/>nnen,
	aber im Datenmodell enthalten die Text-Knoten
	dann nur diese Zeichen.
	Von den genauen Grenzen der CDATA-Abschnitte
	sowie von der Entity-Struktur wird also abstrahiert.</I>
<I>Der Wurzel-Knoten und die Element-Knoten
	haben eine geordnete Liste von Kind-Knoten.
	Element-Knoten haben au<ss/>erdem eine Menge von Attribut-Knoten.
	Diese z<ae/>hlen nicht als Kinder,
	aber umgekehrt z<ae/>hlt der Element-Knoten
	als Vater der Attribut-Knoten.
	(Diese Festlegung ist wichtig f<ue/>r die genaue Bedeutung
	der Achsen in Pfad-Ausdr<ue/>cken, s.u.)
	Schlie<ss/>lich hat jedes Element auch eine Menge
	von Namespace-Knoten
	(einen f<ue/>r jede Namespace-Deklaration,
	in deren G<ue/>ltigkeitsbereich sich dieses Element befindet).
	Auch sie z<ae/>hlen nicht als Kinder des Elementes,
	w<ae/>hrend das Element umgekehrt als Vater gilt.</I>
<I>Es k<oe/>nnen niemals zwei Text-Knoten unmittelbar benachbart sein.
	Textknoten erstrecken sich immer <ue/>ber einen gr<oe/><ss/>t-m<oe/>glichen
	Bereich,
	zwei benachbarte Text-Knoten w<ue/>rden zu einem verschmolzen werden.</I>
<I>Einige Typen von Knoten
	(Elemente, Attribute, Namespaces, Processing-Instructions)
	haben Namen,
	die sich aus einer Namespace-URL und einem lokalen Namen
	zusammensetzen.
	Die Namespace-URL kann leer sein.
	Alle Knoten haben eine Zeichenkette als Wert.</I>
<I>Text-Knoten haben keinen Namen.
	Ihr Wert ist der im Knoten abgespeicherte Text.</I>
<I>Element-Knoten haben den Element-Typ als Namen,
	wobei ggf.<n/>ein Namespace-K<ue/>rzel durch
	die entsprechende URL ersetzt wird.
	Der Wert eines Element-Knotens
	ist der reine Text (ohne Markup)
	im Inhalt dieses Elementes.
	D.h.<n/>der Wert eines Knotens ist
	die Konkatenation der Werte aller Text-Knoten,
	die Nachfahren dieses Knotens sind
	(in der Reihenfolge eines Preorder-Durchlaufes).</I>
<I>Der Namen eines Attribut-Knotens
	ist der Name des Attributes,
	der Wert des Knotens ist der Wert des Attributes.
	Attribut-Knoten werden f<ue/>r alle explizit spezifizierten Attribute
	angelegt,
	sowie auch f<ue/>r Attribute,
	die in der DTD mit Default-Wert deklariert sind.
	Im Datenmodell gibt es keinen Unterschied
	zwischen der expliziten Wertangabe im Start-Tag
	und der impliziten Wertangabe <ue/>ber einen Default-Wert.
	Allerdings mu<ss/> nicht jeder XML-Parser eine externe DTD verarbeiten,
	in welchem Fall die Knoten f<ue/>r implizit spezifizierte Attribute
	fehlen.
	F<ue/>r optionale Attribute (<ICODE><IMPLIED/></ICODE>),
	f<ue/>r die nicht explizit ein Wert spezifiziert ist,
	werden keine Knoten angelegt.</I>
<I>Namespace-Knoten haben das Namespace-K<ue/>rzel als Namen,
	ihr Wert ist die zugeh<oe/>rige URL.</I>
<I>Processing-Instructions haben das Ziel als Namen,
	und den danach folgenden String (ohne f<ue/>hrende Leerzeichen)
	als Wert.</I>
<I>Kommentar-Knoten haben keinen Namen.
	Ihr Wert ist der Text des Kommentares.</I>
<I>Der Wurzel-Knoten hat keinen Namen.
	Sein Wert ist der gesamte Text des Dokumentens
	(au<ss/>erhalb von Markup,
	d.h.<n/>ohne Tags, Kommentare, etc.).</I>
<I>Auf den Knoten des Baumes wird eine lineare Ordnung definiert
	(``Dokument-Ordnung''),
	die im Prinzip der Ordnung durch die Position des erste Zeichens
	der XML-Repr<ae/>sentation des Knotens im Eingabe-Dokument entspricht
	(nach der Ersetzung von Entities).
	Genauer ist die Reihenfolge jeweils zuerst der Vaterknoten,
	dann alle zugeh<oe/>rigen Namespace-Knoten in beliebiger Reihenfolge,
	dann alle zugeh<oe/>rigen Attribut-Knoten in beliebiger Reihenfolge,
	dann die lineare Reihenfolge des ersten Kindknotens
	und aller seiner Nachfahren,
	die lineare Reihenfolge des zweiten Kindknotens
	und aller seiner Nachfahren, u.s.w.</I>
<I>Das Datenmodell ist im Abschnitt<n/>5 der XPath-Spezifikation beschrieben
	<URL>http://www.w3.org/TR/xpath#data-model</URL>.</I>
</LIST>
</SECTION>

<SECTION>
<H>Pfad-Ausdr<ue/>cke</H>
<LIST>
<I>Pfadausdr<ue/>cke dienen in XPath dazu,
	eine Menge von Knotem im Baum des Eingabe-Dokumentes
	zu selektieren.</I>
<I>Die Bedeutung von Pfadausdr<ue/>cken ist abh<ae/>ngig vom Kontext.
	Dieser Kontext spezifiziert insbesondere einen Startknoten
	(``context node'').
	Im obigen Stylesheet ist dieser Startknoten
	die Wurzel des Baumes.
	Wenn Transformationsregeln sich rekursiv aufrufen,
	k<oe/>nnen aber auch andere Knoten Startknoten sein.</I>
<I>Au<ss/>erdem wird f<ue/>r den Kontext davon ausgegangen,
	da<ss/> der Startknoten Element einer Liste von Kontext-Knoten ist.
	Es ist tats<ae/>chlich nur die Position in dieser Liste
	und ihre L<ae/>nge wichtig.
	Damit kann z.B.<n/>getestet werden,
	ob der Startknoten der erste oder der letzte Knoten
	in der Kontext-Liste ist.</I>
<I>Ein relativer Pfadausdr<ue/>ck ist eine Folge von Selektions-Schritten,
	getrennt durch<n/>``<ICODE>/</ICODE>'', z.B.
	<CODE>
	<L>BOOKLIST/BOOK/AUTHOR/@LAST</L>
	</CODE>
	Jeder Schritt w<ae/>hlt eine Menge von Knoten
	bei gegebenem Start-Knoten aus.
	Jeder der von einem Schritt gelieferten Knoten
	wird als Startknoten f<ue/>r den n<ae/>chsten Schritt verwendet.
	Die so bestimmten Knotenmengen
	(f<ue/>r alle diese Start-Knoten)
	werden vereinigt.</I>
<I>Ein absoluter Pfad-Ausdruck besteht aus einem ``<ICODE>/</ICODE>''
	gefolgt von einem relativen Pfad-Ausdruck.
	Hier beginnt die Abarbeitung immer bei dem Wurzelknoten
	des Dokumentes,
	das den gegebenen Start-Knoten enth<ae/>lt.</I>
<I>F<ue/>r die einzelnen Selektions-Schritte
	gibt es eine allgemeine und eine abgek<ue/>rzte Syntax.
	Internet Explorer<n/>5 scheint nur die abgek<ue/>rzte Syntax
	zu verstehen.
	Apache Xalan kann beide Varianten verarbeiten.</I>
<I>In der allgemeinen Syntax besteht ein Selektions-Schritt
	aus einer Achsen-Angabe,
	einem Knoten-Test,
	und einer optionalen Liste von Pr<ae/>dikaten.
	Achsen-Angabe und Knoten-Test sind durch ``<ICODE>::</ICODE>''
	getrennt,
	Pr<ae/>dikate sind in ``<ICODE>[...]</ICODE>'' eingeschlossen.
	Das obige Beispiel s<ae/>he in der allgemeinen Syntax so aus
	(es verwendet keine Pr<ae/>dikate):
	<CODE>
	<L>child::BOOKLIST/child::BOOK/child::AUTHOR/attribute::LAST</L>
	</CODE>
	Die wichtigsten Abk<ue/>rzungs-Regeln sind
	da<ss/> man ``<ICODE>child::</ICODE>'' weglassen kann
	(die Kind-Achse ist der Default)
	und ``<ICODE>attribute::</ICODE>'' zu ``<ICODE>@</ICODE>''
	abk<ue/>rzen darf.</I>
<I>Im allgemeinen bestimmt die Achsen-Angabe eine Menge von Kandidat-Knoten
	bez<ue/>glich ihrer Position im Baum
	relativ zum gegebenen Start-Knoten.
	Es gibt folgende Achsen:
	``<ICODE>child</ICODE>'',
	``<ICODE>descendant</ICODE>'',
	``<ICODE>parent</ICODE>'',
	``<ICODE>ancestor</ICODE>'',
	``<ICODE>following-sibling</ICODE>'',
	``<ICODE>preceding-sibling</ICODE>'',
	``<ICODE>following</ICODE>'',
	``<ICODE>preceding</ICODE>'',
	``<ICODE>attribute</ICODE>'',
	``<ICODE>namespace</ICODE>'',
	``<ICODE>self</ICODE>'',
	``<ICODE>descendant-or-self</ICODE>'',
	``<ICODE>ancestor-or-self</ICODE>''.
	Die Bedeutung der meisten Achsen versteht sich von selbst,
	im Zweifelsfall schaue man in Abschnitt<n/>2.2
	der XPath-Spezifikation nach
	<URL>http://www.w3.org/TR/xpath<HASH/>axes</URL>.
	Der Anfang von Abschnitt<n/>2 enth<ae/>lt auch eine l<ae/>ngere Liste
	von Beispielen
	sowie den Beginn der Grammatik f<ue/>r Pfad-Ausdr<ue/>cke
	<URL>http://www.w3.org/TR/xpath<HASH/>location-paths</URL>.
	<NOTE>Im Internet Explorer sind <ue/>ber die Abk<ue/>rzungen
	nur die Achsen
	``<ICODE>child</ICODE>'',
	``<ICODE>descendant</ICODE>'',
	``<ICODE>attribute</ICODE>'',
	und ``<ICODE>self</ICODE>'' implementiert.
	F<ue/>r ``<ICODE>parent</ICODE>'' gibt es eine Abk<ue/>rzung
	(``<ICODE>..</ICODE>''),
	aber sie scheint vom Internet Explorer
	nicht verstanden zu werden.</NOTE></I>
<I>Der zweite Teil eines Selektions-Schrittes
	ist der Knoten-Test.
	Er bezieht sich auf den Namen und den Typ des Knotens.
	Wenn nichts anderes angegeben ist,
	werden bei allen Achsen au<ss/>er ``<ICODE>attribute</ICODE>''
	und ``<ICODE>namespace</ICODE>'' nur Element-Knoten ausgew<ae/>hlt
	(bei ``<ICODE>attribute</ICODE>'' entsprechend Attribut-Knoten
	und bei ``<ICODE>namespace</ICODE>'' Namespace-Knoten).
	Der Knoten-Test besteht dann in der Angabe eines Namens.
	Es werden diejenigen Knoten ausgew<ae/>hlt,
	deren Element-Typ (bzw.<n/>Attribut-Name bzw.<n/>Namespace-K<ue/>rzel)
	mit dem angegebenen Namen <ue/>bereinstimmt
	(bei Elementen und Attributen nach Ersetzung des Namespace-K<ue/>rzels
	durch die zugeh<oe/>rige URL).
	Anstelle eines Namens kann man auch ``<ICODE>*</ICODE>'' verwenden,
	dann werden alle Knoten des jeweiligen Typs ausgew"hlt.
	Die Form ``<ICODE>xyz:*</ICODE>'' ist auch erlaubt,
	sie w<ue/>rde alle Elemente (bzw.<n/>Attribute) des gegebenen
	Namespaces ausw<ae/>hlen.</I>
<I>Falls man mit dem durch die Achse bestimmten Knoten-Typ nicht zufrieden ist,
	kann man auch eine der folgenden f<ue/>nf Formen
	von Knotentests verwenden:
	``<ICODE>node()</ICODE>'' w<ae/>hlt alle Knoten aus,
	die <ue/>ber die gegebene Achse erreichbar sind,
	``<ICODE>comment()</ICODE>'' w<ae/>hlt Kommentar-Knoten aus,
	``<ICODE>text()</ICODE>'' w<ae/>hlt Text-Knoten aus,
	``<ICODE>processing-instruction()</ICODE>''
	w<ae/>hlt Processing-Instructions aus,
	und ``<ICODE>processing-instruction('abc')</ICODE>''
	w<ae/>hlt Processing-Instructions
	f<ue/>r das Programm <ICODE>abc</ICODE> aus
	(d.h.<n/>der Form ``<ICODE><PI>abc<n/>...</PI></ICODE>'').
	Bei der letzten Form kann man statt einfachen
	auch doppelte Anf<ue/>hrungszeichen verwenden.
	Bei allen diesen Knoten-Tests kann nicht zus<ae/>tzlich
	ein Name spezifiziert werden,
	das w<ue/>rde aber auch keinen Sinn machen,
	da nur Elemente, Attribute, und Namespaces Namen haben.</I>
<I>Knoten-Tests sind genauer beschrieben im Abschnitt<n/>2.3 der Spezifikation
	<URL>http://www.w3.org/TR/xpath#node-tests</URL>,
	siehe auch Abschnitt<n/>3.7
	<URL>http://www.w3.org/TR/xpath#exprlex</URL>.</I>
<I>Neben den bereits erw<ae/>hnten zwei Abk<ue/>rzungen
	(``<ICODE>child::</ICODE>'' kann weggelassen werden
	und ``<ICODE>attribute::</ICODE>'' kann durch ``<ICODE>@</ICODE>''
	ersetzt werden)
	gibt es noch drei weitere:
	``<ICODE>//</ICODE>'' ist eine Abk<ue/>rzung f<ue/>r
	``<ICODE>/descendant-or-self::node()/</ICODE>'',
	``<ICODE>..</ICODE>'' ist eine Abk<ue/>rzung f<ue/>r
	``<ICODE>parent::node()</ICODE>'',
	und ``<ICODE>.</ICODE>''
	ist eine Abk<ue/>rzung f<ue/>r ``<ICODE>self::node()</ICODE>''.
	Abk<ue/>rzungen sind ausf<ue/>hrlich behandelt
	(mit vielen Beispielen) im Abschnitt<n/>2.5 der Spezifikation
	<URL>http://www.w3.org/TR/xpath#path-abbrev</URL>.</I>
<I>Schlie<ss/>lich kann man Pfadausdr<ue/>cke noch mit ``<ICODE>|</ICODE>''
	verkn<ue/>pfen,
	dies liefert die Vereinigung der selektierten Knoten.</I>
</LIST>
</SECTION>

<SECTION>
<H>Aufgaben</H>
<LIST>
<I>Was ist die ausf<ue/>hrliche Fassung
	des Pfadausdrucks ``<ICODE>//AUTHOR/@LAST</ICODE>''?
	Was w<ue/>rde dieser Ausdruck im Beispiel-Dokument ausgeben?</I>
<I>Und was w<ue/>rde ``<ICODE>//AUTHOR</ICODE>'' im Beispiel ausgeben?
	Beachten Sie,
	da<ss/> ``<ICODE>xsl:value-of</ICODE>'' im Stylesheet
	den oben beim Datenmodell definierten Wert der selektierten Knoten
	ausgibt.</I>
<I>Was w<ue/>rde entsprechend f<ue/>r ``<ICODE>//BOOK</ICODE>''
	ausgegeben?</I>
<I>Was w<ue/>rde ``<ICODE>/BOOKLIST/BOOK//*</ICODE>'' ausgeben?</I>
<I>Was w<ae/>re das Ergebnis von
	``<ICODE>/BOOKLIST/BOOK/@*</ICODE>''?</I>
<I>Was ist der Unterschied von ``<ICODE>.//TITLE</ICODE>''
	und ``<ICODE>//TITLE</ICODE>''
	(wenn ein bestimmtes <ICODE>BOOK</ICODE>-Element
	als Start-Knoten vorgegeben ist)?</I>
<I>Macht es einen Unterschied,
	ob man im Stylesheet
	``<ICODE>//TITLE</ICODE>'' oder ``<ICODE>//TITLE/text()</ICODE>''
	schreibt?</I>
</LIST>
</SECTION>

<SECTION>
<H>Pr<ae/>dikate</H>
<LIST>
<I>Pr<ae/>dikate dienen dazu,
	das Ergebnis eines Selektions-Schrittes im Pfad
	noch weiter zu filtern
	(d.h.<n/>nur eine Teilmenge der Knoten
	an den n<ae/>chsten Selektions-Schritt weiterzugeben).</I>
<I>Pr<ae/>dikate werden in eckige Klammern eingeschlossen.
	Zum Beispiel w<ue/>rde dieser Ausdruck
	den Titel des Buches mit der ISBN ``<ICODE>0-13-014714-1</ICODE>''
	ausgeben:
	<CODE>
	<L>/BOOKLIST/BOOK[@ISBN='0-13-014714-1']/TITLE</L>
	</CODE></I>
<I>Zwischen den eckigen Klammern mu<ss/> ein Ausdruck (``expression'') stehen,
	wie in Abschnitt<n/>3 der Spezifikation definiert
	<URL>http://www.w3.org/TR/xpath#section-Expressions</URL>.
	Dieser Ausdruck mu<ss/> einen  boolschen Wert liefern,
	aber XPath hat sehr gro<ss/>z<ue/>gige Konvertierungs-
	und Abk<ue/>rzungs-Regeln.</I>
<I>Ein solcher Ausdruck wird wieder f<ue/>r einen Kontext
	ausgewertet,
	der insbesondere einen Start-Knoten festlegt.
	Im vorigen Beispiel wird etwa der Ausdruck ``<ICODE>@ISBN</ICODE>''
	relativ zu einem Start-Knoten ausgewertet,
	was in diesem Fall der Reihe nach alle <ICODE>BOOK</ICODE>-Knoten
	sind:
	<CODE>
	<L>/BOOKLIST/BOOK[@ISBN='0-13-014714-1']/TITLE</L>
	</CODE></I>
<I>Teil des Kontextes ist auch
	die Position des Start-Knotens in der aktuellen Knoten-Liste,
	und die L<ae/>nge der Knoten-Liste.
	Verwendet man den Ausdruck als Pr<ae/>dikat in einem Selektions-Schritt,
	so besteht die aktuelle Knoten-Liste aus allen Knoten,
	die den Knoten-Test dieses Schrittes geschafft haben
	(f<ue/>r jeweils einen festen Start-Knoten aus dem vorangegangenen
	Selektions-Schritt).
	Zum Beispiel liefert folgender Ausdruck
	den ersten Autor jedes Buches:
	<CODE>
	<L>/BOOKLIST/BOOK/AUTHOR[position()=1]/@LAST</L>
	</CODE>
	Die Funktion ``<ICODE>position()</ICODE>''
	liefert gerade die Position des Start-Knotens
	in der aktuellen Knoten-Liste.
	Internet Explorer versteht wieder nur die abgek<ue/>rzte Form:
	<CODE>
	<L>/BOOKLIST/BOOK/AUTHOR[1]/@LAST</L>
	</CODE>
	Falls das Pr<ae/>dikat eine Zahl liefert,
	wird diese mit der Position des Start-Knotens
	in der aktuellen Knotenliste verglichen.
	Stimmen Sie <ue/>berein,
	ist das Pr<ae/>dikat erf<ue/>llt.
	Im Internet Explorer wird die Position allerdings von 0 an gez<ae/>hlt,
	um jeweils den ersten Autor zu bekommen,
	mu<ss/> man also schreiben:
	<CODE>
	<L>/BOOKLIST/BOOK/AUTHOR[0]/@LAST</L>
	</CODE>
	Der Standard sagt dagegen ausdr<ue/>cklich,
	da<ss/> die erste Position<n/>1 ist.
	Siehe Abschnitt<n/>2.4
	<URL>http://www.w3.org/TR/xpath<HASH/>predicates</URL>.
	<NOTE>Vor der endg<ue/>ltigen Ver<oe/>ffentlichung
	wurde die XSLT/XPath-Spezifikation aber mehrfach ge<ae/>ndert,
	und die Namespace-URL im Internet Explorer zeigt,
	da<ss/> er sich auf einen fr<ue/>heren ``Working Draft''
	bezieht.
	Es ist m<oe/>glich,
	da<ss/> damals die Z<ae/>hlung mit 0 begann.</NOTE>
	<NOTE>Falls man eine der Achsen ``<ICODE>achestor</ICODE>'',
	``<ICODE>anchestor-or-self</ICODE>'',
	``<ICODE>preceding</ICODE>''
	oder ``<ICODE>preceding-sibling</ICODE>'' gew<ae/>hlt hat
	wird die Liste von aktuellen Knoten
	in der umgekehrten Dokument-Ordnung angeordnet,
	so da<ss/> zum Beispiel<n/><ICODE>[1]</ICODE>
	immer den zum vorigen Start-Knoten am n<ae/>chsten liegenden Knoten
	liefert.
	Im Internet Exporer<n/>5 k<oe/>nnen diese Achsen allerdings
	sowieso nicht verwendet werden.</NOTE></I>
<I>Die Funktion ``<ICODE>last()</ICODE>''
	liefert die L<ae/>nge der aktuellen Knotenliste
	aus dem Kontext.
	Folgender Ausdruck w<ue/>rde zum Beispiel
	den Nachnamen des letzten Autors jedes Buches ermitteln:
	<CODE>
	<L>/BOOKLIST/BOOK/AUTHOR[last()]/@LAST</L>
	</CODE>
	Im Internet Explorer mu<ss/> man ``<ICODE>end()</ICODE>''
	statt ``<ICODE>last()</ICODE>'' schreiben.</I>
<I>Manchmal kann es nach einem Pr<ae/>dikat n<ue/>tzlich sein,
	wieder im Baum aufzusteigen.
	Der folgende Ausdruck liefert z.B.<n/>die Titel aller B<ue/>cher
	mit mindestens zwei Autoren:
	<CODE>
	<L>/BOOKLIST/BOOK/AUTHOR[2]/../TITLE</L>
	</CODE>
	Der Internet Explorer scheint aber kein ``<ICODE>..</ICODE>''
	zu verstehen
	(abgesehen davon,
	da<ss/> man dort den dritten Autor selektieren w<ue/>rde).</I>
<I>Mit Pr<ae/>dikaten kann auch die Existenz von bestimmten Knoten
	getestet werden.
	Liefert ein Pr<ae/>dikat eine Menge von Knoten
	(d.h.<n/>ist ein Pfad-Ausdruck),
	so z<ae/>hlt es als wahr,
	wenn diese Menge nicht leer ist.
	Zum Beispiel liefert folgender Ausdruck
	die Titel aller B<ue/>cher,
	die eine Anmerkung haben:
	<CODE>
	<L>/BOOKLIST/BOOK[NOTE]/TITLE</L>
	</CODE></I>
<I>Man kann in Ausdr<ue/>cken die <ue/>blichen arithmetischen Operatoren
	verwenden (<ICODE>+</ICODE>, <ICODE>-</ICODE>, <ICODE>*</ICODE>,
	<ICODE>div</ICODE>, <ICODE>mod</ICODE>).
	Zum Beispiel bekommt man den vorletzten Autor mit:
	<CODE>
	<L>/BOOKLIST/BOOK/AUTHOR[last()-1]/@LAST</L>
	</CODE>
	Im Internet Explorer wird dies nicht unterst<ue/>tzt.</I>
<I>Man kann die <ue/>blichen Vergleichs-Operatoren verwenden
	(<ICODE>=</ICODE>, <ICODE>!=</ICODE>,
		<ICODE>&lt;</ICODE>, <ICODE>&lt;=</ICODE>,
		<ICODE>&gt;</ICODE>, <ICODE>&gt;=</ICODE>).
	Allerdings wird man bei Verwendung von XPath-Ausdr<ue/>cken
	in XML-Dokumenten (z.B.<n/>XSLT-Stylesheets)
	das <ICODE>&lt;</ICODE>-Zeichen
	als <ICODE><EREF>lt</EREF></ICODE> eingeben m<ue/>ssen.
	Au<ss/>erdem sind <ICODE>&lt;</ICODE>, <ICODE>&lt;=</ICODE>
	<ICODE>&gt;</ICODE>, und <ICODE>&gt;=</ICODE>
	nach dem Standard nur f<ue/>r Zahlen definiert,
	nicht f<ue/>r Zeichenketten.
	Der Internet-Explorer unterst<ue/>tzt diese Operatoren
	dagegen auch f<ue/>r Zeichenketten,
	und bietet au<ss/>erdem ``case insensitive'' Versionen an,
	z.B.<n/>``<ICODE><D/>ieq<D/></ICODE>''.
	Als Beispiel seien die Titel aller B<ue/>cher
	mit mehr als 500<n/>Seiten selektiert:
	<CODE>
	<L>/BOOKLIST/BOOK[@PAGES > 500]/TITLE</L>
	</CODE></I>
<I>In Vergleichen wird bei Bedarf ein Knoten in einen String
	umgewandelt,
	indem sein Wert genommen wird.
	Dies haben wir schon im ersten Beispiel
	<CODE>
	<L>/BOOKLIST/BOOK[@ISBN='0-13-014714-1']/TITLE</L>
	</CODE>
	gesehen,
	denn dort liefert ``<ICODE>@ISBN</ICODE>'' zun<ae/>chst
	den Attribut-Knoten,
	und nicht direkt den Wert.
	Entsprechend ist auch folgendes m<oe/>glich:
	<CODE>
	<L>/BOOKLIST/BOOK[TITLE='XML Pocket Reference']/AUTHOR</L>
	</CODE>
	Bei Bedarf kann der String auch weiter in eine Zahl
	umgewandelt werden.
	Dies geschieht etwa im obigen Beispiel
	<CODE>
	<L>/BOOKLIST/BOOK[@PAGES > 500]/TITLE</L>
	</CODE></I>
<I>Nun ist es m<oe/>glich,
	da<ss/> der Pfad-Ausdruck im Pr<ae/>dikat eine ganze Menge
	von Knoten liefert.
	Vergleiche mit einer Menge von Knoten gelten als wahr,
	wenn der Vergleich f<ue/>r wenigstens einen Knoten der Menge
	wahr ist
	(d.h.<n/>es wird hier ein impliziter Existenz-Quantor verwendet).
	Zum Beispiel liefert der folgende Ausdruck
	die Titel aller B<ue/>cher,
	von denen Goldfarb ein Autor ist.
	Es st<oe/>rt dabei nicht,
	da<ss/> es noch andere Autoren gibt:
	<CODE>
	<L>/BOOKLIST/BOOK[AUTHOR/@LAST='Goldfarb']/TITLE</L>
	</CODE>
	<NOTE>Im Internet Explorer kann man durch Voranstellen
	von <ICODE><D/>all<D/></ICODE> und <ICODE><D/>any<D/></ICODE>
	das gew<ue/>nschte Verhalten ausw<ae/>hlen.
	Dies ist aber nicht (mehr) im Standard enthalten.
	Standard-Konform kann man durch 
	<ICODE>not(not(...))</ICODE> den Allquantor bekommen.
	<ICODE>not(AUTHOR/@LAST!='Goldfarb')</ICODE>
	w<ue/>rde ebenfalls sicherstellen,
	da<ss/> Goldfarb einziger Autor ist.</NOTE></I>
<I>Man kann in Ausdr<ue/>cken die <ue/>blichen logischen Junktoren
	``<ICODE>and</ICODE>'' und ``<ICODE>or</ICODE>'' verwenden.
	Zum Beispiel liefert folgender Ausdruck
	die Titel aller B<ue/>cher,
	die mehr als 300 Seiten haben
	und 1999 oder sp<ae/>ter erschienen sind:
	<CODE>
	<L>/BOOKLIST/BOOK[@PAGES>300 and PUBLISHER/@DATE>=19990101]/TITLE</L>
	</CODE></I>
<I>Abschnitt<n/>4 der Spezifikation z<ae/>hlt eine ziemlich lange Liste
	von eingebauten Funktionen auf,
	die man ebenfalls in Ausdr<ue/>cken verwenden kann
	<URL>http://www.w3.org/TR/xpath#corelib</URL>.
	Zum Beispiel gibt es
	eine boolesche Funktion ``<ICODE>contains</ICODE>'',
	mit der man einen Test auf Teil-Zeichenketten
	durchf<ue/>hren kann:
	<CODE>
	<L>/BOOKLIST/BOOK[contains(TITLE, 'Reference')]/TITLE</L>
	</CODE>
	Diese Funktion ist nicht im Internet Explorer implementiert
	(wie alle/fast alle anderen Funktionen der Liste,
	daf<ue/>r hat der Internet Explorer einige eigenen ``Methoden'').
	Au<ss/>erdem ist zu beachten,
	da<ss/> hier nicht die ``Existenz''-Semantik
	bei mehreren L<oe/>sungen gilt.
	Wenn eine Menge von Knoten Eingabe f<ue/>r eine Funktion ist,
	die einen String erwartet,
	wird einfach der erste Knoten umgewandelt
	(und alle anderen ignoriert).
	Daher funktioniert etwa das folgende Beispiel nicht
	(Goldfarb ist zweiter Autor):
	<CODE>
	<L>/BOOKLIST/BOOK[contains(AUTHOR/@LAST, 'oldfa')]/TITLE</L>
	</CODE></I>
</LIST>
</SECTION>

<SECTION>
<H>Aufgaben</H>
<LIST>
<I>Es sei folgende XML-Datei mit Informationen
	<ue/>ber Knomponisten und ihre Musikst<ue/>cke gegeben:
	<CODE>
	<L><XDECL>version="1.0"</XDECL></L>
	<L><BEG>MUSIC</BEG></L>
	<L><T/><BEG>COMPOSER BORN=<QUOT/>1678<QUOT/>
			DIED=<QUOT/>1741<QUOT/></BEG></L>
	<L><T/><T/><BEG>NAME</BEG>Vivalidi<END>NAME</END></L>
	<L><T/><T/><BEG>PIECE TYPE=<QUOT/>Concert<QUOT/></BEG
			>The Four Seasons<END>PIECE</END></L>
	<L><T/><END>COMPOSER</END></L>
	<L><T/><BEG>COMPOSER BORN=<QUOT/>1685<QUOT/>
			DIED=<QUOT/>1750<QUOT/></BEG></L>
	<L><T/><T/><BEG>NAME</BEG>Bach<END>NAME</END></L>
	<L><T/><T/><BEG>PIECE TYPE=<QUOT/>Mass<QUOT/></BEG
			>B-minor Mass<END>PIECE</END></L>
	<L><T/><T/><BEG>PIECE</BEG>Christmas Oratorio<END>PIECE</END></L>
	<L><T/><END>COMPOSER</END></L>
	<L><T/><BEG>COMPOSER BORN=<QUOT/>1756<QUOT/>
			DIED=<QUOT/>1791<QUOT/></BEG></L>
	<L><T/><T/><BEG>NAME</BEG>Mozart<END>NAME</END></L>
	<L><T/><T/><BEG>PIECE TYPE=<QUOT/>Mass<QUOT/></BEG
			>Missa Solemnis<END>PIECE</END></L>
	<L><T/><END>COMPOSER</END></L>
	<L><T/><BEG>COMPOSER BORN=<QUOT/>1891<QUOT/>
			DIED=<QUOT/>1953<QUOT/></BEG></L>
	<L><T/><T/><BEG>NAME</BEG>Prokofiev<END>NAME</END></L>
	<L><T/><T/><BEG>PIECE TYPE=<QUOT/>Symphony<QUOT/></BEG
			>Classical Symphony<END>PIECE</END></L>
	<L><T/><T/><BEG>PIECE TYPE=<QUOT/>Ballet<QUOT/></BEG
			>Cinderella<END>PIECE</END></L>
	<L><T/><END>COMPOSER</END></L>
	<L><T/><BEG>COMPOSER BORN=<QUOT/>1841<QUOT/>
			DIED=<QUOT/>1904<QUOT/></BEG></L>
	<L><T/><T/><BEG>NAME</BEG>Dvorak<END>NAME</END></L>
	<L><T/><END>COMPOSER</END></L>
	<L><END>MUSIC</END></L>
	</CODE></I>
<I>Geben Sie einen XPath-Ausdruck an,
	der die Namen aller Komponisten in der XML-Datenbank selektiert.</I>
<I>Drucken Sie die Titel aller St<ue/>cke vom Typ ``<ICODE>Symphony</ICODE>''
	aus.</I>
<I>Drucken Sie die Namen aller Komponisten aus,
	die um 1700 gelebt haben.</I>
<I>Gesucht sind die Namen aller Komponisten,
	die eine Sinfonie geschrieben haben
	(gem<ae/><ss/> den in der Datenbank verzeichneten St<ue/>cken).</I>
<I>Geben Sie die Namen aller Komponisten aus,
	von denen mehr als ein St<ue/>ck in der Datenbank ist.</I>
</LIST>
</SECTION>

</CHAPTER>
</COURSENOTES>

