Donnerstag, 4. Dezember 2008





April 2006
aus XML & Web Services Magazin Ausgabe: 2.2003
Auf den Weg gebracht
Die XML-Anfragesprache XQuery im Praxiseinsatz
von Wolfgang Lezius

Die Anfragesprache XQuery ist auf dem besten Wege, ein Standard zur Abfrage von XML-Dokumenten zu werden. Die jüngsten Spezifikationen zeigen vielversprechende Ansätze, mit der endgültigen Verabschiedung ist Mitte 2003 zu rechnen. Doch um zu einem wirklichen Standard zu werden, muss eine Anfragesprache ausdrucksstark und zugleich intuitiv sein. Der vorliegende Artikel untersucht an einem konkreten Anwendungsbeispiel, inwieweit diese Kriterien von XQuery erfüllt werden.


Ein fehlender Standard zur Abfrage von XML-Dokumenten hat viele Entwickler bislang davon abgehalten, XML-Anfragesysteme einzusetzen. Erste Ansätze wie XQL oder XML-QL waren zwar sehr vielversprechend, konnten sich aber auf Grund zu schwacher Ausdruckskraft oder unzureichender Implementierungen nicht durchsetzen. Das World Wide Web Consortium (W3C) hat dieses Dilemma bereits 1998 erkannt und eine Arbeitsgruppe zur Spezifikation eines neuen Anfragestandards eingesetzt. Das ehrgeizige Ziel dieser Arbeitsgruppe bestand darin, eine Anfragesprache zu schaffen, die die herausragenden Eigenschaften der verfügbaren XML-Anfragesprachen integriert und mit dem bewährten Design der Anfragesprachen SQL und OQL verbindet. Als Ergebnis ist XQuery entstanden, das in der aktuellen Spezifikation vom November 2002 vorliegt. Da für diese Spezifikation noch keine vollständige Implementierung vorliegt (Stand: Januar 2003), wird in diesem Artikel die Spezifikation vom August 2002 zu Grunde gelegt ([1],[2]). Einige Experten sagen XQuery eine strahlende Zukunft voraus - die Sprache könnte das SQL des 21. Jahrhunderts werden. Im Folgenden wird untersucht, ob dem W3C tatsächlich der ganz große Wurf gelungen ist. Dazu wird ein einfaches Anwendungsbeispiel aus der Praxis vorgestellt, in dessen Kontext XQuery seine Stärken unter Beweis stellen soll.

XQuery und XPath 2.0
Bereits früh zeichnete sich ab, dass die Pfadbeschreibungssprache XPath einen zentralen Bestandteil von XQuery bilden würde. Da XPath auch ein wichtiger Bestandteil von XSLT ist und sich eine weitere Arbeitsgruppe mit der Weiterentwicklung von XSLT befasst (bezeichnet als XSLT 2.0), arbeiten die beiden Arbeitsgruppen XQuery und XSLT 2.0 seit etwa einem Jahr eng zusammen. Ergebnis dieser Kooperation ist die Weiterentwicklung von XPath (bezeichnet als XPath 2.0), das an Mächtigkeit deutlich zugelegt hat [3]. XPath 2.0 ist aber nicht nur ein Bestandteil von XQuery, jeder XPath 2.0-Ausdruck ist zugleich eine vollwertige XQuery-Anfrage. Tatsächlich liegt der Anteil von XPath 2.0 an der XQuery-Spezifikation bei über 80 Prozent. Daraus folgt: Wer sich mit XQuery beschäftigt, lernt das neue XPath 2.0 ganz nebenbei!

Grundlegende Konzepte
Bevor die Anfragesprache in einem konkreten Anwendungsbeispiel eingesetzt werden kann, müssen zunächst einige zentrale Konzepte besprochen werden, die für XPath 2.0 gelten und damit auch für XQuery relevant sind. Einige wesentliche Neuerungen liegen bereits im Bereich der Datentypen. So sind alle primitiven Datentypen wie string, boolean oder auch date aus der XML Schema-Spezifikation übernommen worden (vgl. [6]), wodurch sich gegenüber XPath 1.0 ein deutlich breiteres Spektrum an Datentypen ergibt. Die bekannten XML-Knoten-Datentypen (element, attribute, comment usw.) sind hier ebenfalls enthalten. Zu dem sehr breiten Spektrum an Datentypen ergibt sich auch eine große Anzahl vordefinierter Funktionen, die auf diesen Datentypen operieren. Die in XPath 2.0 definierten Funktionen und Operatoren werden vom W3C in einem separaten Dokument beschrieben [4].


Mit den Sequenzen (sequences) ist ein zentraler Datentyp hinzugekommen, der die aus XPath 1.0 bekannten Knotenmengen (node-sets) ablöst (vgl. auch [7]). Zentraler Gedanke dabei ist, dass Knotenmengen streng genommen keine Ordnung besitzen können. Die Anordnung einer Knotenmenge nach der Anordnung des XML-Dokuments (z.B. bei der Prozessierung in XSLT-Stylesheets) war lediglich eine Konvention. Eine Sequenz stellt dagegen eine angeordnete Liste dar, die die Dokumentknoten stets in der Dokumentreihenfolge verwaltet. Sequenzen können aber auch beliebige andere unterstützte Datentypen enthalten und stellen damit einen sehr leistungsfähigen Datentyp dar. Beispiel: (1, 2, 1, "hallo"). Wie dieses Beispiel zeigt, sind in Sequenzen doppelte Einträge erlaubt. Eine Sequenz stellt grundsätzlich eine flache Struktur dar, womit (1,(2,3)) und (1,2,3) dieselbe Sequenz repräsentieren. Als Sonderfall wird jede Instanz eines primitiven Datentyps zugleich als eine Sequenz bestehend aus genau dieser einen Instanz aufgefasst. Beispiel: 1 ist gleichbedeutend mit (1). Die sich aus dieser Definition ergebenden Vorteile werden im Laufe dieses Artikels illustriert.


In XPath 2.0 und XQuery wird jede gültige Suchanfrage bzw. jede XPath-Beschreibung als Ausdruck bezeichnet ([1]). Jeder primitive Wert wie 3 stellt bereits einen vollständigen Ausdruck dar. Neben den bekannten Ausdruckstypen wie arithmetischen oder booleschen Ausdrücken definieren XPath 2.0 und XQuery eine Reihe weiterer Ausdruckstypen. Die zentralen Ausdruckstypen werden im Folgenden im Praxiseinsatz illustriert.

Das Anwendungsbeispiel
Da im wissenschaftlichen Bereich Veröffentlichungen eine zentrale Rolle spielen, präsentieren viele Institute ihre Publikationen im Rahmen eines Web-Auftritts. Am Institut für Maschinelle Sprachverarbeitung verwenden wir zur Verwaltung der Publikationsdaten ein XML-Dokument, die Auswahl und Formatierung der Daten erfolgt mit XSLT-Stylesheets [5]. Diese Lösung ist insofern nicht ideal, als XSLT bei einer komplexeren Auswahl schnell umständlich und zuweilen sogar ineffizient wird. An dieser Stelle setzt XQuery an, das zur eleganten und effizienten Auswahl von Daten eingesetzt werden soll. Die Formatierung der Ergebnisdaten bleibt dann XSLT-Stylesheets vorbehalten. Listing 1 zeigt eine exemplarische Instituts-Bibliographie bestehend aus zwei Publikationen. Auf der Heft-CD finden Sie eine umfangreichere Bibliographie sowie alle im weiteren Verlauf entwickelten Suchanfragen.


Um als Eingabe von XSLT-Stylesheets verarbeitet werden zu können, müssen die Ergebnisdaten der XQuery-Anfragen in XML vorliegen. XQuery-Anfragen können aber ebenso HTML oder ein beliebiges anderes Format als Ausgabe erzeugen. Die Verwendung von XML ist allerdings flexibler, da mit XSLT-Stylesheets beliebige weitere Zielformate erzeugt werden können.


Listing 1

<bibliography>

<publication type="article">
<title>Statistische Wortartenannotierung für das Deutsche</title>
<authors>
<author>
<lastname>Rapp</lastname>
<firstname>Reinhard</firstname>
</author>
<author>
<lastname>Lezius</lastname>
<firstname>Wolfgang</firstname>
</author>
</authors>
<year>2001</year>
<reference>Sprache und Datenverarbeitung, 25(2)</reference>
</publication>

<publication type="article">
<title>Ein starkes Team? Eine Einführung in XML und XSLT</title>
<authors>
<author>
<lastname>Fitschen</lastname>
<firstname>Arne</firstname>
</author>
<author>
<lastname>Lezius</lastname>
<firstname>Wolfgang</firstname>
</author>
</authors>
<year>2001</year>
<reference>Java Magazin 9/2001 und 10/2001</reference>
</publication>

</bibliography>

Beispiel 1: Autorenliste
Als erstes Fallbeispiel wollen wir aus dem Bibliographie-Dokument eine Liste aller Autoren gewinnen. Als Ausgangspunkt dient der folgende Ausdruck, der alle -Elemente des Dokuments extrahiert:

document("bib.xml")/bibliography/publication/authors/author

Dieser Ausdruck ist abwärtskompatibel zu XPath 1.0. Bei der Prozessierung wird zunächst das Bibliographie-Dokument bib.xml eingeladen. Anschließend werden alle -Elemente des Dokuments ermittelt, die dem angegebenen Pfad <bibliography>-<publication>- entsprechen. Im Gegensatz zu XPath 1.0 ist das Ergebnis jedoch keine Knotenmenge, sondern eine Sequenz von Elementen. Ein XQuery-Prozessor wird die Elemente in der Ergebnis-Sequenz in der Regel zu einem XML-Ergebnisdokument zusammenfassen, das von einem generierten Wurzelelement umrahmt wird. Die in Listing 2 gezeigte Ausgabe wird beispielsweise von QuiP erzeugt (vgl. Abschnitt Verfügbare XQuery-Prozessoren).


Listing 2

<quip:result>

<author>
<lastname>Rapp</lastname>
<firstname>Reinhard</firstname>
</author>
<author>
<lastname>Lezius</lastname>
<firstname>Wolfgang</firstname>
</author>
<author>
<lastname>Fitschen</lastname>
<firstname>Arne</firstname>
</author>
<author>
<lastname>Lezius</lastname>
<firstname>Wolfgang</firstname>
</author>

</quip:result>


Eine erste Verbesserung der Anfrage besteht darin, das doppelte Auftreten von Autoren (hier: Autor Lezius) zu verhindern. Dazu wird die Funktion distinct-values eingesetzt. Sie entfernt doppelte Einträge innerhalb der Ergebnissequenz:

distinct-values(document("bib.xml")/bibliography/publication/authors/author)

Die erzeugte Autorenliste soll lediglich aus Nachnamen bestehen. Dazu müssen die in der Sequenz ermittelten -Elemente durchlaufen und pro Element nur der Nachname ausgegeben werden. Dazu wird ein so genannter for-Ausdruck verwendet:

for $author in (distinct-values(document("bib.xml")/
bibliography/publication/authors/author))
return $author/lastname

Der for-Ausdruck durchläuft die hinter dem Schlüsselwort in angegebene Sequenz. Die einzelnen Sequenz-Einträge werden dabei in der Variablen $author abgelegt. Dem Schlüsselwort return folgt ein weiterer Ausdruck, der die für jeden Eintrag zu erzeugende Ausgabe festlegt. Im Beispiel wird für jeden Sequenz-Eintrag lediglich das eingebettete <lastname>-Element ausgegeben. Das Ergebnis eines for-Ausdrucks ist wieder eine Sequenz, die aus den erzeugten Ausgabewerten besteht. Im Beispiel wird also eine Sequenz von <lastname>-Elementen erzeugt:

<quip:result>

<lastname>Rapp</lastname>
<lastname>Lezius</lastname>
<lastname>Fitschen</lastname>

</quip:result>

Bis zu dieser Anfrage haben wir uns in den genannten 80 Prozent der XQuery-Spezifikation bewegt, die aus XPath 2.0-Ausdrücken bestehen. Das Ergebnis ist jedoch noch nicht perfekt, es fehlt eine alphabetische Sortierung der Nachnamen. Dazu wird ein sort-Ausdruck verwendet, der nicht mehr Bestandteil von XPath 2.0 ist. Ein sort-Ausdruck wird einem Ausdruck nachgestellt:

for $author in (distinct-values(document("bib.xml")/
bibliography/publication/authors/author))
return $author/lastname
sort by (.)

Der sort-Ausdruck sortiert die im vorangestellten for-return-Ausdruck beschriebene Sequenz. Sollte der Ausdruck keine Sequenz, sondern ein primitiver Datentyp sein, so wird der Ausdruckswert per Definition als einelementige Sequenz aufgefasst. Der nach dem Schlüsselwort by angegebene Suchausdruck legt fest, nach welchem Kriterium die Sortierung erfolgen soll. Im Beispiel wird durch das Kontextsymbol . das <lastname>-Element bzw. dessen Elementinhalt als Sortierkriterium markiert.

Beispiel 2: Autoren und ihre Publikationen
Der nächste Schritt besteht darin, die Publikationen aller Autoren aufzulisten, die dem Institut angehören. Die im ersten Beispiel erzeugte Autorenliste kann für diesen Zweck nicht verwendet werden, da sie auch Mitarbeiter anderer Forschungseinrichtungen enthalten kann. Da die Zugehörigkeit eines Autors zum Institut in der XML-Datei nicht kodiert ist, muss diese zusätzliche Information von außen kommen. Eine Lösung besteht darin, ein Instituts-Autorenverzeichnis zu erstellen (vgl. Listing 3) und mit in die XQuery-Anfrage einzubinden. Aus diesem Verzeichnis ist beispielsweise ersichtlich, dass der Autor Rapp nicht Mitarbeiter des Instituts ist und in der neuen Liste nicht mehr auftreten darf.


Listing 3

<authorlist>

<author>
<lastname>Lezius</lastname>
<firstname>Wolfgang</firstname>
</author>
<author>
<lastname>Fitschen</lastname>
<firstname>Arne</firstname>
</author>
<author>
<lastname>IchPubliziereNicht</lastname>
<firstname>Rudi</firstname>
</author>

</authorlist>


Zur Verknüpfung der beiden XML-Dokumente gibt es mehrere Möglichkeiten. Eine Lösung bildet den aus relationalen Datenbanken bekannten Join nach. Zur Vereinfachung geben wir für jeden Autor zunächst nur diejenigen Publikationen aus, bei denen er als Erstautor angegeben ist. Zentraler Bestandteil der Suchanfrage ist ein for-where-return-Ausdruck:

for $employee in (document("authors.xml")/authorlist/author),
$paper in document("bib.xml")/bibliography/publication
where deep-equal($employee, $paper/authors/author[1])
return <author>
{$employee/lastname}
{$paper}
</author>

Zunächst werden im for-Ausdruck alle Paare von Mitarbeitern des Instituts in Form von -Elementen und Publikationen der Bibliographie in Form von <publication>-Elementen ausgelesen. Jedes Paar wird durch die Belegungen der beiden Variablen $employee und $paper repräsentiert. Ist nun für ein Paar die im where-Ausdruck formulierte Bedingung erfüllt, so wird die im return-Ausdruck angegebene Ausgabe in die Ergebnis-Sequenz übernommen.


Im Beispiel wird jedes -Element als Belegung der Variablen $employee mit dem ersten -Element innerhalb der Publikation $paper (authors/author[1]) verglichen. Die für den Vergleich verwendete deep-equal()-Funktion stellt sicher, dass zwei Knoten genau dann als gleich angesehen werden, wenn alle ihre eingebetteten Substrukturen (hier: im Element eingebettete Elemente und Elementinhalte) übereinstimmen.


Bei der Festlegung des return-Ausdrucks wird erstmals die Ausgabe umstrukturiert. Dazu wird das XML-Element erzeugt, indem es wie in einem XSLT-Stylesheet einfach in den Suchausdruck eingefügt wird. Der Name des neuen Elements ist dabei beliebig und hätte beispielsweise auch <institutsautor> lauten können. Damit die für jedes neue -Element angegebenen einzubettenden Elemente nicht als Text, sondern als auszuwertender Ausdruck interpretiert werden, müssen die Ausdrücke ebenfalls wie in XSLT durch geschweifte Klammern gekennzeichnet werden.


Nachteil der Join-Lösung ist die Strukturierung des Ergebnisses, die sich nach den Autor-Publikation-Paaren richtet und eine Gruppierung nach dem Autor erschwert. Die folgende Alternative erlaubt nicht nur eine Gruppierung, sie ist sogar übersichtlicher:

for $employee in (document("authors.xml")/authorlist/author)
let $papers := document("bib.xml")/bibliography/publication
[deep-equal(authors/author[1], $employee)]
return <author>
{$employee/lastname}
{$papers}
</author>

Für jeden Mitarbeiter - repräsentiert durch ein -Element als Belegung der Variablen $employee - werden zunächst alle Publikationen ermittelt, bei denen der Mitarbeiter als Erstautor angegeben ist. Die Variablenzuweisung nach dem Schlüsselwort let weist dazu der Variablen $papers alle Publikationen des Autors als Sequenz zu. Die in eckigen Klammern angegebene Bedingung sorgt dafür, dass der Vergleich des ersten -Elements der Publikation mit dem -Element des Mitarbeiters erfolgt. Im Unterschied zur Join-Lösung durchläuft der for-Ausdruck nun keine Paare mehr, sondern alle Mitarbeiter. Die Gruppierung erfolgt daher auf elegante Art und Weise, wie auch die erzeugte Ausgabe (Listing 4) zeigt.


Listing 4

<quip:result>

<author>
<lastname>Lezius</lastname>
</author>

<author>
<lastname>Fitschen</lastname>
<publication>
<title>Ein starkes Team? Eine Einführung in XML und XSLT</title>

</publication>
</author>

<author>
<lastname>IchPubliziereNicht</lastname>
</author>

</quip:result>


Es verbleiben noch einige kleinere Verbesserungen:
  • Der bisherige Erstautorvergleich muss noch durch einen generelleren Vergleich ersetzt werden (vgl. leere Publikationsliste des Autors Lezius im obigen Ergebnis). Dazu wird ein Existenzquantor verwendet, da mindestens einer der Autoren einer Publikationen der gewünschte Mitarbeiter sein muss. Durch den folgenden Ausdruck wird genau diese Bedingung beschrieben: some $author in ./authors/author satisfies deep-equal($author,$employee)
  • Der zuletzt angegebene Mitarbeiter IchPubliziereNicht hat keine Publikationen verfasst. Er sollte daher nicht in der Liste auftreten. Durch das Einfügen einer Bedingung (Schlüsselwort where) kann die Ausgabe auf diejenigen Autoren begrenzt werden, die mindestens eine Publikation vorzuweisen haben. Die Funktion count() berechnet die Länge einer Sequenz, die im vorliegenden Fall die Länge 0 überschreiten muss.
  • Alle Publikationen werden bislang als Geschwister des -Elements ausgegeben. Aus Gründen des Dokumentdesigns sollten sie besser in einem neuen -Element eingebettet werden. Als zusätzliche Information wird die bereits verwendete Anzahl der Publikationen als amount-Attribut im -Element eigetragen.

Als Ergebnis ergibt sich der XQuery-Ausdruck in Listing 5. Das zugehörige Anfrage-Ergebnis sieht nun aus wie in Listing 6 gezeigt.


Listing 5

for $employee in (document("authors.xml")/authorlist/author)
let $papers := document("bib.xml")/bibliography/publication
[some $author in ./authors/author satisfies
deep-equal($author,$employee)]
where count($papers)>0

return <author>
{$employee/lastname}
<publications amount="{count($papers)}">
{$papers}
</publications>
</author>
sort by (.)


Listing 6

<quip:result>

<author>
<lastname>Fitschen</lastname>
<publications amount="1">
<publication>
<title>Ein starkes Team? Eine Einführung in XML und XSLT</title>

</publication>
</publications>
</author>

<author>
<lastname>Lezius</lastname>
<publications amount="2">
<publication>
<title>Statistische Wortartenannotierung für das Deutsche</title>

</publication>
<publication>
<title>Ein starkes Team? Eine Einführung in XML und XSLT</title>

</publication>
</publications>
</author>

</quip:result>

Beispiel 3: Publikationsliste
Einige sehr interessante und ausdrucksstarke Möglichkeiten von XQuery ergeben sich im dritten Fallbeispiel. Dazu drehen wir die Fragestellung um und versuchen nun, statt einem Verzeichnis aller Autoren und ihrer Publikationen eine sauber formatierte und sinnvoll gruppierte Aufstellung aller Publikationen zu erreichen. Als Ausgangspunkt dient folgender Suchausdruck, der lediglich alle Publikationen nach ihrer Reihenfolge im XML-Dokument anordnet und ausgewählte Angaben zur Publikation in die Ausgabe übernimmt:

for $paper in document("bib.xml")/bibliography/publication

return <publication>
{$paper/title}
{$paper/year}
{$paper/authors}
</publication>

Diese Form der Präsentation ist sicher noch nicht ideal. Eine übersichtliche Darstellung gruppiert die einzelnen Publikationen nach ihrem Erscheinungsjahr. Die folgende Anfrage gewinnt dazu zunächst eine Sequenz aus allen in den Publikationen angegebenen Jahreszahlen. Durch die Verwendung der distinct-values-Funktion werden doppelte Einträge aussortiert, der nachfolgende sort-Ausdruck sorgt für die nötige Sortierung. Das Schlüsselwort descending veranlasst die absteigende Sortierung, sodass aktuelle Publikationen immer ganz oben stehen. Bei der Ausgabe werden die zusammengehörigen Publikationen explizit durch ein <group>-Element zusammengefasst, um einem weiterverarbeitenden Stylesheet so viel Arbeit wie möglich zu ersparen.

for $year in ( (distinct-values(document("bib.xml")/bibliography/publication/year))
sort by (. descending)
)

let $yearpapers := document("bib.xml")/bibliography/publication[year = $year]

return <group year="{$year}">
{ for $paper in ($yearpapers)
return <publication>
{$paper/title}
{$paper/year}
{$paper/authors}
</publication>
}
</group>

Das Anfrageergebnis sieht damit folgendermaßen aus:

<quip:result>

<group year="2001">

<publication type="article">
<title>Statistische Wortartenannotierung für das Deutsche</title>
...
</publication>

<publication type="article">
<title>Ein starkes Team? Eine Einführung in XML und XSLT</title>
...
</publication>

</group>

</quip:result>

Die Publikationsliste liegt nun bereits in einer Form vor, die von einem Stylesheet mit wenigen Handgriffen in ein Zielformat wie HTML konvertiert werden kann. Zum Schluss soll eine weitere spezielle Publikationsliste erzeugt werden, die nur aus Publikationen besteht, die ausschließlich von Institutsmitarbeitern verfasst wurden. Dazu wird ein Allquantor benötigt. Ein Allquantor stellt ein sehr ausdrucksstarkes Hilfsmittel dar, das viele zusätzliche Möglichkeiten eröffnet.


Die zur Verfeinerung benötigten Ergänzungen sind dabei schnell eingeführt. Ein let-Ausdruck zu Beginn der Anfrage hält für den späteren Autorenvergleich die Liste aller Institutsautoren als Sequenz in der Variablen $employees fest. Es verbleibt lediglich eine kleine Verfeinerung der Ausgabe, die die Publikationen unter Beteiligung von Fremdautoren aussortiert. Die nach dem Schlüsselwort where formulierte Bedingung überprüft, ob für jeden Autor der Publikation gilt: Dieser Autor stimmt mit einem Autoren der in $employees gespeicherten Institutsautoren überein. Hier wird also ein Allquantor mit einem Existenzquantor verbunden (siehe Listing 7).


Listing 7

let $employees := document("authors.xml")/authorlist/author

for $year in ( (distinct-values(document("bib.xml")/bibliography/publication/year))
sort by (. descending)
)

let $yearpapers := document("bib.xml")/bibliography/publication[year = $year]

return <group year="{$year}">
{ for $paper in ($yearpapers)
where
(every $author in $paper/authors/author satisfies
(some $employee in $employees satisfies
(deep-equal($employee,$author))
)
)
return <publication>
{$paper/title}
{$paper/year}
{$paper/authors}
</publication>
}
</group>


Die erweiterte Anfrage ermittelt gegenüber der obigen Ausgabe nur noch einen Artikel (Ein starkes Team?...) der Publikationsliste. Auf der Heft-CD befindet sich noch eine weitere Anfrage, die die Definition und Verwendung von benutzereigenen Funktionen illustriert. Damit ist das Repertoire von XQuery zwar noch längst nicht ausgeschöpft, die wesentlichen Eigenschaften und Möglichkeiten sind jedoch im Rahmen dieses Anwendungsbeispiels aufgezeigt worden.

Verfügbare XQuery-Prozessoren
Die ausgefeilteste Anfragesprache ist natürlich wertlos, solange nicht entsprechend leistungsfähige Anfrageprozessoren zur Verfügung stehen. Da die endgültige XQuery-Spezifikation erst Mitte 2003 verabschiedet wird, sind bislang lediglich prototypische Implementierungen verfügbar. Eine aktuelle Liste aller erhältlichen Suchwerkzeuge ist auf der XQuery-Seite des W3C zu finden ([9]). Es ist damit zu rechnen, dass unmittelbar nach der XQuery-Verabschiedung weitere XQuery-Implementationen bzw. XQuery-Unterstützungen diverser Produkte folgen werden. Die beiden Darmstädter Firmen Software AG und Infonyte bereiten entsprechende Erweiterungen für ihre XML-Datenbanken Tamino XML Server bzw. Infonyte-DB bereits vor.


Zwei gelungene Prototypen werden an dieser Stelle vorgestellt. Das Tool IPSI-XQ ist vom Darmstädter Institut für Integrierte Publikations- und Informationssysteme (IPSI) der Fraunhofer-Gesellschaft entwickelt worden. Laut den Lizenzvereinbarungen auf der Download-Seite ([10]) steht es für nicht-kommerzielle Zwecke kostenlos zur Verfügung. IPSI-XQ unterstützt bereits in weiten Teilen die XQuery-Spezifikationen vom August 2002 und November 2002. Alle in diesem Artikel entwickelten XQuery-Anfragen sind mit der Version 1.1.1b ohne Änderungen lauffähig. Die Installation des vollständig in Java entwickelten Tools erfolgt durch Anpassen einer Batch-Datei bzw. eines Shell-Skripts. Interessant ist die Möglichkeit, das Tool mit Hilfe einer Java-Schnittstelle auch in eigene Programme einzubinden.


Das frei verfügbare Werkzeug QuiP wird von der Software AG angeboten [11]. Es ist als Add-on für den Tamino XML Server gedacht, arbeitet aber auch völlig eigenständig auf Datei-Basis. Die aktuelle Version 2.2.1 unterstützt leider nur die Spezifikation vom April 2002. Um die Anfragen dieses Artikels dennoch mit QuiP testen zu können, befinden sich auf der Heft-CD alle Anfragen zusätzlich in einer Variante, die der älteren XQuery-Spezifikation genügt. QuiP verwendet zwar eine in Java implementierte Benutzeroberfläche, greift zur Anfrage-Auswertung jedoch auf eigens für die Plattformen Windows und Linux kompilierte Programme zu. Die Installation erfolgt auch bei QuiP durch Anpassen einer Batch-Datei bzw. eines Shell-Skripts. Die Benutzeroberfläche wirkt sehr ansprechend und schließt wichtige Features wie Syntax-Highlighting der XQuery-Anfrage oder ansprechende Formatierung der Ausgabeformate XML und HTML ein.

Fazit
Auch wenn die endgültige Spezifikation noch nicht verabschiedet ist und als Implementierungen bislang nur Prototypen zur Verfügung stehen - XQuery ist auf dem besten Wege, der XML-Anfragestandard der Zukunft zu werden. Das Design der Sprache ist äußerst gelungen und knüpft an bestehende Sprachen wie SQL an bzw. setzt auf der erweiterten Pfadbeschreibungssprache XPath 2.0 auf. Dadurch ist XQuery die Unterstützung einer breiten Anwenderschaft gewiss. Wie der vorliegende Artikel zeigt, genügt eine kurze Einarbeitungszeit, um erste XQuery-Projekte zu realisieren. Die Ausdruckskraft der Sprache ist dabei so umfassend, dass das Anwendungsbeispiel nur Teilaspekte illustrieren konnte. Entscheidend für die Akzeptanz von XQuery wird jedoch die Unterstützung durch die Hersteller sein. Nur wenn führende Anbieter von XML-Datenbanken bzw. Datenbanken mit XML-Unterstützung rasch nach dem Erscheinen der W3C Recommendation eine XQuery-Schnittstelle vorstellen, wird sich der vielversprechende Ansatzes auch wirklich etablieren.

Wolfgang Lezius ist wissenschaftlicher Mitarbeiter am Institut für Maschinelle Sprachverarbeitung der Universität Stuttgart. In seiner Dissertation hat er sich mit der Entwicklung eines plattformunabhängigen Anfragesystems für linguistisch annotierte Texte befasst (www.tigersearch.de). Im Rahmen dieses Projekts werden insbesondere Technologien aus dem Java- und XML-Umfeld eingesetzt.

Links und Literatur
W3C-Dokumente:
Literaturhinweise:
  • [5] Wolfgang Lezius, Ein Java Servlet zur Online-Präsentation von Daten mit XML und XSLT, Java Magazin 3.2001, S. 91-94
  • [6] Michael Seemann, XML Schema Tutorial, Java Magazin 11.2002 und 12.2002
  • [7] Manfred Knobloch, Neuerungen in den Entwürfen zu XSLT 2.0 und XPath 2.0, XML & Web Services Magazin 2.2002, S. 43-45
  • [8] Michael Seemann, Native XML-Datenbanken für Dokumente und Daten, XML & Web Services Magazin 2.2002, S. 30-36

Tools:


    Hat Ihnen dieser Artikel gefallen? Dann abonnieren Sie das Entwickler Magazin direkt über unser Online-Formular.

zur vorherigen Seite
zurück
an den Anfang der Seite
nach oben
Diesen Artikel drucken
drucken
Diesen Artikel weiterempfehlen
empfehlen




Software & Support Verlag GmbH