Rudolf Jansen XQuery
Rudolf Jansen
XQuery Eine praxisorientierte Einführung
Software & Support Verlag 2004
Jansen, Rudolf: XQuery. Eine praxisorientierte Einführung. Frankfurt, 2004 ISBN 3-935042-65-5
© 2004 Software & Support Verlag GmbH
http://www.software-support-verlag.de http://www.entwickler.com/buecher/xquery
Bibliografische Information Der Deutschen Bibliothek Die Deutsche Bibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.ddb.de abrufbar.
Umschlaggestaltung: Melanie Hahn Korrektorat: Martha-Luise Lessing Belichtung, Druck und Bindung: M.P. Media-Print Informationstechnologie GmbH, Paderborn. Alle Rechte, auch für Übersetzungen, sind vorbehalten. Reproduktion jeglicher Art (Fotokopie, Nachdruck, Mikrofilm, Erfassung auf elektronischen Datenträgern oder andere Verfahren) nur mit schriftlicher Genehmigung des Verlags. Jegliche Haftung für die Richtigkeit des gesamten Werks kann, trotz sorgfältiger Prüfung durch Autor und Verlag, nicht übernommen werden. Die im Buch genannten Produkte, Warenzeichen und Firmennamen sind in der Regel durch deren Inhaber geschützt.
Inhaltsverzeichnis
Inhaltsverzeichnis Vorwort.....................................................................................................7 1 Einführung..........................................................................................9 1.1 Zielgruppe ....................................................................................9 1.1.1 Themenabgrenzung............................................................9 1.1.2 Voraussetzungen..............................................................10 1.1.3 Kapitelübersicht ...............................................................11 1.2 Was ist XQuery? ........................................................................13 1.3 Standardisierung.........................................................................15 1.3.1 Historie.............................................................................15 1.3.2 Anforderungen .................................................................19 1.3.3 Andere XML-Standards...................................................20 1.4 Zusammenfassung......................................................................39 2 Sprachbestandteile ...........................................................................41 2.1 Beispieldaten ..............................................................................41 2.2 FLWOR-Ausdrücke ...................................................................44 2.2.1 Variablenbindung ............................................................50 2.2.2 Filterung...........................................................................53 2.2.3 Sortierung.........................................................................57 2.2.4 Rückgabewert ..................................................................61 2.3 Operatoren..................................................................................68 2.3.1 Logische Operatoren........................................................69 2.3.2 Arithmetische Operatoren................................................71 2.3.3 Vergleichs-Operatoren.....................................................72 2.3.4 Reihenfolge-Operatoren ..................................................83 2.4 Typkonzept.................................................................................85 2.4.1 Atomare Werte.................................................................87 2.4.2 Benutzerdefinierte Typen ................................................96 2.4.3 Typoperatoren..................................................................98 2.4.4 Konvertierung ................................................................102 5
Inhaltsverzeichnis
2.5 Funktionen ...............................................................................103 2.5.1 Inputfunktionen .............................................................103 2.5.2 Vordefinierte Funktionen ..............................................105 2.5.3 Textfunktionen...............................................................109 2.5.4 Benutzerdefinierte Funktionen ......................................113 2.5.5 Externe Funktionen........................................................119 2.6 Module und Prolog...................................................................119 2.7 Joins..........................................................................................122 2.8 Fehlerbehandlung.....................................................................125 3 Implementierungen........................................................................129 3.1 Ausführungsschritte .................................................................131 3.1.1 Statische Verarbeitungsschritte .....................................132 3.1.2 Dynamische Verarbeitungsschritte................................134 3.2 Verfügbare Implementierungen ...............................................135 3.2.1 IPSI ................................................................................136 3.2.2 Qexo...............................................................................137 3.2.3 Sonstige .........................................................................141 3.2.4 BumbleBee ....................................................................144 3.3 Java-Anbindung .......................................................................145 3.3.1 Herstellerspezifische Lösungen.....................................146 3.3.2 XQJ ................................................................................147 4 Anwendungen .................................................................................153 4.1 Systemintegration.....................................................................154 4.2 Webanwendungen....................................................................154 4.3 Fazit..........................................................................................155 Literatur ...............................................................................................159 Autor .....................................................................................................161 Index......................................................................................................163
6
Vorwort
Vorwort Die Zahl der im XML-Umfeld veröffentlichten Publikationen für neue Sprachbestandteile ist nur noch schwer zu überschauen. Aus diesem Grund habe ich der ersten Ankündigung eines weiteren neuen Standards mit Namen XQuery beim ersten Lesen keine besonders hohe Aufmerksamkeit geschenkt. Erst als ich einen kurzen Artikel über diesen weiteren Standard in einer Fachzeitschrift gelesen hatte, bin ich neugierig geworden und habe mich intensiver mit XQuery beschäftigt. Da ich mich in meiner Tätigkeit als freiberuflicher Software-Entwickler häufig sowohl mit XML als auch mit relationalen Datenbanken und deren Abfragesprache SQL beschäftige, bin ich seit dem ersten intensiven Studium der neuen Sprache XQuery davon überzeugt, dass diese eine ähnliche Bedeutung wie SQL erlangen wird. Sehr schnell kam daher die Idee, ein einführendes Buch über XQuery zu schreiben, das im Vergleich zur sehr theorielastigen Sprachspezifikation praxisorientiert anhand von Sourcecode-Beispielen die wichtigsten Sprachbestandteile vorstellen soll. Das größte „Hindernis“ bei der Entscheidung für dieses Buchprojekt war die Tatsache, dass die endgültige erste Version der Sprache XQuery zum Zeitpunkt der Erstellung dieses Buches im Sommer 2004 noch nicht verabschiedet war. Die im Frühjahr 2004 vorliegende relativ stabile Spezifikationsversion ist dann aber doch zur Grundlage für dieses Buch geworden. Auch wenn kleinere Änderungen am Sprachumfang in der endgültigen Version natürlich nie ganz auszuschließen sind, so sollten eigentlich keine gravierenden Änderungen an den grundlegenden Sprachbestandteilen, die in diesem Buch vorgestellt werden, mehr zu erwarten sein. Für Fragen, Kritik und Anregungen stehe ich unter der Mailadresse
[email protected] gerne zur Verfügung.
7
Vorwort
Bedanken möchte ich mich bei den Mitarbeitern des Software & SupportVerlages für die Unterstützung bei der Planung und Erstellung dieses Buches sowie bei den Entwicklern der XQuery-Implementierung IPSI, die in Kapitel 3.2.1 dieses Buches vorgestellt wird und unter deren Einsatz ich die Beispiele dieses Buches entwickelt habe. Der größte Dank gilt aber meiner Familie, ohne deren Geduld und Verständnis dieses Buchprojekt nicht möglich gewesen wäre.
Rudolf Jansen Aachen, im August 2004
8
Einführung
1 Einführung 1.1
Zielgruppe
Wenn Sie sich für den Kauf dieses Buches entschieden haben oder gerade in der Buchhandlung zum ersten Mail in diesem Buch blättern, dann haben Sie wahrscheinlich den Begriff „XQuery“ schon vorher irgendwo gehört oder gelesen. Sie wissen also bereits, dass XQuery eine Abfragesprache für XMLDaten aller Art ist. Möglicherweise haben Sie auch bereits kleinere Beispiele dieser „neuen“ Sprache gesehen, die Sie neugierig gemacht haben. Das vorliegende Buch ist eine praxisorientierte Einführung in die Abfragesprache XQuery, in dem anhand von Beispielen die zugrunde liegenden Konzepte und Sprachbestandteile vorgestellt werden. Neben der Sprache selber soll aber auch die Anwendung von XQuery behandelt werden. Zu diesem Zweck werden einige zum Zeitpunkt der Erstellung dieses Buches bereits verfügbare Implementierungen vorgestellt. Und auch die Frage, in welchen Anwendungen bzw. Projekten XQuery sinnvoll eingesetzt werden kann, sowie die Abgrenzung gegenüber verwandten Standards wie XML-Schema, XPath und XSLT sind Schwerpunkte dieses Buches.
1.1.1 Themenabgrenzung Bevor die Buchinhalte kurz vorgestellt werden, sollte zunächst festgelegt werden, was dieses Buch nicht ist bzw. welche Themen Sie besser in anderen Werken mit anderen Schwerpunkten suchen sollten. Ziel des Buches ist – wie bereits erwähnt – eine praxisbezogene Einführung in XQuery. Daher wurde nicht mehr als unbedingt nötig von den theoretischen Grundlagen von XQuery sowie dem eng verwandten XPath in das Buch aufgenommen. Dies soll keine Abwertung der Theoriethemen darstellen: Sie gehören zu jedem Standard dazu und bilden die Grundlage für die nach außen sichtbaren Praxis-Features. Eine umfassende Behandlung dieser Themen hätte aber einerseits den angestrebten Umfang dieses Buches gesprengt (alleine die W3C-Spezifikation zum „XPath 2.0 und XQuery 1.0“9
Zielgruppe
Datenmodell umfasst knapp 60 Seiten). Außerdem wäre dann auch der Praxis-Schwerpunkt des Buches in den Hintergrund gerückt. Wer sich für Details der theoretischen Grundlagen interessiert, der sei entweder auf die zugrunde liegenden W3C-Spezifikationen [XQDM] oder das Buch [Kat03] verwiesen, in dem die Mitglieder der W3C-Arbeitsgruppe XQuery u.a. zu diesen Themen ausführliche Kapitel geschrieben haben. Dieses Buch wendet sich an Nutzer der XQuery-Technologie, also an Personen, die mithilfe einer vorliegenden XQuery-Implementierung die Sprache XQuery erlernen wollen und/oder XQuery in einem konkreten Projekt einsetzen wollen. In Kapitel 3 werden daher einige bereits verfügbare Implementierungen vorgestellt. Nicht Bestandteil dieses Buches sind dagegen Gesichtspunkte, die bei der Erstellung einer XQuery-Engine erforderlich sind. Bezüglich der dazu benötigten Kenntnisse beispielsweise auf dem Gebiet der Query-Optimierung sei an dieser Stelle ebenfalls auf das Werk [Kat03] sowie diverse Publikationen zur Grundlagen-Forschung (z.B. [VLDB03], [XIME04], [XSym03]) verwiesen.
1.1.2 Voraussetzungen Sie sollten über grundlegende XML-Kenntnisse verfügen, wenn Sie mit dem vorliegenden Buch XQuery erlernen wollen. Diese XML-Kentnisse müssen zwar nicht für alle XML-Details vorhanden sein, die wichtigsten XMLBegriffe wie Elemente, Attribute etc. sollten Ihnen aber bekannt sein. Wie in den folgenden Abschnitten noch erläutert wird, ist XQuery mit den folgenden drei XML-Standards eng verknüpft: • XML-Schema • XPath • XSLT XSLT-Vorkenntnisse sind als Grundlage für dieses Buch nicht erforderlich. XQuery wird zwar häufig als Alternative bzw. Ergänzung zu XSLT angesehen, sodass ein Leser mit XSLT-Kenntnissen beim Studium der XQueryBeispiele unmittelbar die Gemeinsamkeiten und Unterschiede der beiden Sprachen erkennen kann. Aber auch für Leser, die XSLT erst gar nicht lernen
10
Einführung
wollen bzw. müssen, sondern direkt XQuery einsetzen wollen, ist dieses Buch geeignet. Die beiden erstgenannten XML-Standards (XML-Schema und XPath) dagegen werden in XQuery-Konstrukten intensiv genutzt. XML-Schema dient als Grundlage für das Typkonzept von XQuery. XPath 2.0 wurde parallel zu XQuery 1.0 entwickelt, sodass Anforderungen von XQuery in diese neue XPath-Version eingeflossen sind. Diese beiden Standards werden daher bereits am Ende dieses einführenden Kapitels vorgestellt und auch in den Beispielen in Kapitel 2 verwendet. Da der Umfang dieses Buches bewusst knapp gehalten wurde, kann dieses Buch naturgemäß keine umfassende Referenz für XML-Schema und XPath sein. Zum Verständnis der XML-Schema- und XPath-Bestandteile der XQuery-Beispiele sollten die Ausführungen dieses Buches ausreichend sein. Wenn Sie nach Studium dieses Buches von den Möglichkeiten von XQuery überzeugt sind und daher detaillierter in die Nutzung dieser neuen Abfragesprache einsteigen wollen, lohnt sich sicherlich auch ein Blick auf Spezialliteratur zu den verwandten Standards, z.B. [VDF02] für XML-Schema und [Sim02] für XPath. An vielen Stellen wird XQuery mit SQL verglichen werden. Nicht umsonst wird XQuery bereits in diesem sehr frühen Stadium als das „SQL des 21. Jahrhunderts“ bezeichnet. XQuery wird für den Bereich XML-Daten eine ähnliche Bedeutung vorausgesagt, wie es SQL für den Bereich „Relationale Datenbanken“ hat. SQL-Kenntnisse sind zwar nicht zwingend erforderlich, allerdings insbesondere bei den einführenden Beispielen zu den FLWORAusdrücken in Kapitel 2 hilfreich, da die meisten Bestandteile von XQueryAusdrücken mit ähnlichen Bestandteilen von SQL-Abfragen vergleichbar sind.
1.1.3 Kapitelübersicht Was bietet Ihnen dieses Buch nun? Es ist genau das Richtige für Sie, wenn Sie zur beschriebenen Zielgruppe gehören, d.h. wenn Sie ein Buch mit folgender Zielsetzung gesucht haben:
11
Zielgruppe
• • • •
•
Praxisbezogene Einführung in die neue Abfragesprache XQuery, eher knappe Behandlung der theoretischen Grundlagen, Beschränkung auf XQuery sowie die eng verknüpften Standards XMLSchema und XPath, d.h. Verzicht auf Kapitel wie z.B. „Einführung in XML“, Vorstellung verfügbarer Tools mit der Möglichkeit, die Beispiele dieses Buches auf dem eigenen Rechner anhand (frei verfügbarer) XQueryEngines testen und den eigenen Anforderungen z.B. in einem konkreten Projekt anpassen zu können, kritische Diskussion der Vor- und Nachteile, die XQuery in der ersten Version auszeichnen.
In den restlichen Abschnitten dieses ersten Kapitels folgt nun zunächst eine Kurzvorstellung von XQuery sowie der bei der Definition des Standards zugrunde liegenden Anforderungen. Kapitel 1 schließt mit der Vorstellung der mit XQuery eng verknüpften Standards XPath, XML-Schema und XSLT. Hauptkapitel des Buches ist Kapitel 2. Dort werden anhand von Beispielen die wichtigsten Sprachbestandteile von XQuery vorgestellt (u.a. FLWORAusdrücke, Operatoren, Typkonzept, Funktionen). Die Beispiele (XMLDokumente und XQuery-Anfragen) stehen auf den Webseiten dieses Buches http://www.entwickler.com/buecher/xquery zum Download bereit, sodass Sie die Beispiele auch selber am Rechner ausprobieren bzw. sie als Grundlage für Ihre eigenen Skripte verwenden können. Zum Testen der XQuery-Anfragen aus Kapitel 2 kann eine der bereits verfügbaren XQuery-Implementierungen eingesetzt werden. Kapitel 3 stellt eine Auswahl dieser in der Regel frei verfügbaren Engines vor. Die meisten Implementierungen bieten dabei nicht nur Kommandozeilen-Tools an, mit denen XQuery-Skripte aufgerufen werden können. Auch eine Java-Anbindung ist meist im Funktionsumfang enthalten. Ein Problem bei diesen JavaXQuery-APIs ist derzeit noch die herstellerspezifische Syntax. Obwohl die zugrunde liegende Technik bei allen Implementierungen sehr ähnlich bzw. identisch ist, unterscheiden sich die Implementierungen meist in den Details. Kapitel 3.3.2 stellt daher mit XQJ einen Versuch vor, an dieser Stelle einen herstellerübergreifenden Standard zu entwickeln. XQJ steht zwar zum Zeitpunkt der Erstellung dieses Buches erst in einer „Early Draft Review“12
Einführung
Version zur Verfügung, aufgrund der darin schon zu erkennenden Ähnlichkeit zu JDBC ist aber bereits die Relevanz für die Etablierung von XQuery zu erkennen. Spätestens nach der Einführung in die XQuery-Sprachbestandteile sowie den ersten eigenen Experimenten mit der neuen Abfragesprache werden Sie sich die Frage stellen, wo man dies alles in der Praxis sinnvoll einsetzen kann. Kapitel 4 liefert dazu einige Aspekte. Ein Schwerpunkt liegt dabei in der Kombination von Abfragen auf XML-Dokumenten und XML-Datenbanken, wobei XML-Datenbanken reine XML-Datenbanken, aber auch relationale Datenbanken mit XML-Erweiterungen sein können. Als Abschluss des Buches folgt noch eine kurze Diskussion der Möglichkeiten von XQuery. Neben der Frage, was XQuery in der derzeitigen ersten Version schon kann und wofür man es jetzt schon einsetzen kann, liegt ein Schwerpunkt dieses Kapitels auch auf den Features, die in der ersten Version noch fehlen. An dieser Stelle schon zu nennen sind dabei z.B. die fehlenden Update-Möglichkeiten. Nach der Lektüre dieses Buches sollten Sie also in der Lage sein, die Möglichkeiten von XQuery zu beurteilen. Dazu zählt auf der positiven Seite das mit der wachsenden Verbreitung von XML-Daten in Form von Dokumenten und Datenbanken enorme Potenzial von XQuery, das dem etwas marketinglastigen Slogan „XQuery – Das SQL des 21. Jahrhunderts“ in Zukunft durchaus gerecht werden kann. Neben diesen Vorschusslorbeeren sind aber insbesondere in Verbindung mit der 1.0-Version von XQuery einige Kritikpunkte zu beachten, die Sie bei der Entscheidung, ob bzw. in welchen Konstellationen Sie XQuery derzeit schon in produktiven Systemen einsetzen können, bedenken sollten.
1.2
Was ist XQuery?
Kurz zusammengefasst ist XQuery eine typbasierte funktionale Abfragesprache für XML-Daten. In dieser kurzen Definition enthalten sind mehrere Charakteristika, die im Folgenden kurz erläutert werden sollen.
13
Was ist XQuery?
Wie im folgenden Kapitel 1.3 besprochen wird, ist XQuery als Abfragesprache für alle Arten von XML-Daten konzipiert worden, also insbesondere für die beiden großen Gruppen • XML-Dokumente • XML-Datenbanken Wie bereits erwähnt, liegt XQuery eine mit anderen Abfragesprachen gemeinsame Vorgehensweise zugrunde. Vor allem Ähnlichkeiten zu SQL sind nicht zu übersehen. Grundlegendes Konstrukt von XQuery sind Ausdrücke. Als deklarative Sprache legt XQuery in Form von Ausdrücken fest, welche Daten aus den InputDatenbeständen ausgewählt werden sollen. Der entscheidende Unterschied zu prozeduralen Sprachen wie z.B. Java besteht also darin, dass nicht der Weg definiert wird, wie ein Ergebnis erreicht werden soll, sondern nur das Ergebnis selber. Für die Auswertung eines XQuery-Ausdrucks, also den Weg zur Konstruktion des Ergebnisses, ist nicht der XQuery-Nutzer, sondern die eingesetzte XQuery-Engine verantwortlich. Im Gegensatz zu prozeduralen Sprachen, bei denen in der Regel der Entwickler für die Festlegung des exakten Algorithmus der Anwendung verantwortlich ist, kann bzw. muss man sich als Entwickler eines XQuery-Ausdrucks auf die in der eingesetzten XQuery-Engine vordefinierten Regeln zur Abarbeitung des Ausdruckes verlassen. Der Auswahl der passenden XQuery-Engine (s. Kapitel 3) kommt also eine hohe Bedeutung zu. Durch die Festlegung vordefinierter Datentypen sowie die Möglichkeit, über XML-Schema-Definitionen weitere benutzerdefinierte Datentypen in XQuery-Ausdrücken zu verwenden, ist XQuery eine streng typbasierte Sprache. XQuery unterscheidet zwei Arten von Typüberprüfungen: • dynamische Typüberprüfungen und • statische Typüberprüfungen. Während im Rahmen der dynamischen Typüberprüfung zur Laufzeit überprüft wird, ob die im XQuery-Ausdruck definierten bzw. die aus Teilausdrücken ermittelbaren Typen mit denen in den Eingangsdaten übereinstimmen, bieten statische Typüberprüfungen ein interessantes Zusatzfeature gegenüber 14
Einführung
einigen anderen Abfragesprachen. Statische Typüberprüfungen sind eher aus der Welt der prozeduralen Sprachen bekannt, in denen in der Compilephase u.a. Typfehler erkannt werden, sodass diese nicht erst zur Laufzeit bei der Verarbeitung der realen Daten auftreten. Im Rahmen der Vorstellung der XQuery-Sprachbestandteile in Kapitel 2 werden auch Beispiele zu fehlerhaften XQuery-Ausdrücken gezeigt, die während der optionalen Phase der statischen Typüberprüfung entdeckt werden können.
1.3
Standardisierung
1.3.1 Historie Aufgrund der enorm wachsenden Bedeutung von XML nach dessen Einführung in der zweiten Hälfte der 90er-Jahre wurde auch sehr schnell die Nachfrage nach geeigneten Sprachen deutlich, mit denen man XML verarbeiten konnte. Auch wenn in den Anfangsstadien von XML sicher noch nicht absehbar war, dass XML nicht nur als Datenaustauschformat sowie als Format von Konfigurationsdateien Erfolg haben würde, sondern zunehmend auch eine XML-basierte Speicherung von Daten in den Vordergrund treten würde, so war doch SQL als Gegenstück der „relationalen Konkurrenz“ als Vorbild zu erkennen. XQuery-Vorgänger Neben den heute weitläufig eingesetzten Standards wie XML-Schema, XPath und XSLT gab es auch eine Reihe von Versuchen, eine Abfragesprache für XML zu definieren, also ein „SQL für XML-Daten“. Die genannten Standards wie XPath und XSLT können zwar auch für „abfrageähnliche“ Funktionen eingesetzt werden, ihr Schwerpunkt liegt aber eher auf der Navigation und Selektion innerhalb von XML-Dokumenten (XPath) sowie der Formatumwandlung von XML in andere XML-Darstellungen bzw. andere Formate wie z.B. HTML (XSLT). Eine vollständige Abfragesprache vergleichbar mit SQL sind diese Standards aber nicht. Im Laufe der Zeit gab es mehrere Vorschläge für eine XML-Abfragesprache mit den folgenden Bezeichnungen:
15
Standardisierung
• • • • • •
XML-QL XQL XSL Lorel XML-GL Quilt
Die Ursprünge des XQuery-Standards reichen bis in das Jahr 1998 zurück, in dem das World Wide Web Consortium (W3C) einen Workshop zum Thema „XML-Abfragesprachen“ organisierte. Als Folge der auf dieser Konferenz vorgestellten Themen wurde eine Arbeitsgruppe eingesetzt, die sich im Jahre 1999 erstmals traf und am Entwurf einer XML-Abfragesprache arbeitete. Abgrenzung gegenüber SQL Eine der ersten Aufgaben dieser W3C-Arbeitsgruppe war eine Untersuchung, ob SQL geeignet erweitert werden kann, um auch in der XML-Welt eingesetzt zu werden. Kernfrage war dabei, wie XML-Daten – entweder in Dokument-Format oder XML-basiert in einer Datenbank gespeichert – abgefragt werden können. Dies ist nicht zu verwechseln mit der Aufgabe, eine XMLDarstellung von relational gespeicherten Daten zu generieren. Dazu gibt es inzwischen neben herstellerspezifischen SQL-Erweiterungen auch den SQL/XML-Standard, der einige Funktionen wie z.B. XMLElement(), XMLAgg() oder XMLForest() zur Verfügung stellt, mit denen innerhalb von normalen SQL-Select-Abfragen eine XML-Darstellung von relational gespeicherten Daten erzeugt werden kann. Ergebnis der Evaluation von SQL als Kandidat für eine XML-Abfragesprache war allerdings eine Reihe von grundlegenden Unterschieden zwischen relationalen Datenbanken als „Zielgruppe“ von SQL-Abfragen und XML-Daten, die zu der Entscheidung führte, eine neue Sprache zu definieren, die besser auf diese XML-Besonderheiten zugeschnitten ist: • XML liegt eine hierarchische Datenstruktur zugrunde im Gegensatz zur flachen tabellenbasierten Speicherung von relationalen Daten. • Derselbe Unterschied (hierarchische XML-Form gegenüber flachem Tabellenformat) besteht auch beim Ergebnisformat einer XML-Abfrage.
16
Einführung
•
•
Bei einer relationalen Speicherung spielt die Sortierung der Daten keine Rolle. Innerhalb von XML-Dokumenten besteht jedoch eine Ordnung innerhalb der Knotenmenge. Diese Ordnung muss daher auch bei Abfragen berücksichtigt werden können. Erfahrungsgemäß sind relationale Tabellen dichter gefüllt als XMLDokumente. Gemeint ist damit die Tatsache, dass in relationalen Tabellen alle vordefinierten Spalten auch mit Werten belegt sind (entweder mit „realen“ Daten oder mit NULL-Werten). XML-Dokumente dagegen sind häufig dadurch gekennzeichnet, dass sie lückenhafter sind, d.h. nicht alle Elemente gleichen Typs müssen zwangsläufig dieselbe Struktur haben. Ein Beispiel wäre eine Patientendatei in XML-Format: Innerhalb einer XML-Schema-Definition müssen zu allen möglichen Krankheiten, die ein Patient haben kann, Formate (Elemente, Attribute, Constraints etc.) definiert sein, in denen diese dargestellt werden können. In der Realität wird aber natürlich nicht jeder Patient jede Krankheit haben, sodass viele vordefinierte Bestandteile in den auf der XMLSchema-Definition beruhenden XML-Dokumenten fehlen werden. Eine XML-Abfragesprache muss auf solche fehlenden bzw. unterschiedlichen Bestandteile ausgerichtet sein.
Zeitplan Nach der Entscheidung, eine neue XML-Abfragesprache zu definieren, legte die W3C-Arbeitsgruppe, die aus Vertretern von namhaften Firmen und Instituten besteht, im Jahr 2001 einen ersten Entwurf für eine Sprache namens XMLQuery vor. Diese Bezeichnung wurde dann später in XQuery umgewandelt. Ein Hauptziel beim Entwurf von XQuery war eine Integration in die bestehende Familie von XML-Standards. Über die grundlegende Definition des XML-Standards hinaus wurde insbesondere durch XML-Schema und XPath bereits viel Vorarbeit geleistet, die beim Entwurf von XQuery natürlich berücksichtigt werden sollte. Vor allem XPath, das bereits im Jahre 1999 als W3C Recommendation vorlag, wurde in Praxisanwendungen bereits intensiv zur Navigation innerhalb von XML-Daten eingesetzt. Da innerhalb einer XML-Abfragesprache die Themen Navigation und Selektion eine zentrale Rolle spielen und XPath 17
Standardisierung
bereits in anderen XML-Standards wie z.B. XSLT für diese Zwecke eingesetzt wurde, lag es nahe, XPath-Funktionalität auch innerhalb von XQuery zu nutzen. Der Einfluss zwischen den beiden Standards XPath und XQuery bestand aber nicht nur von XPath zu XQuery. Auch XPath selber wurde u.a. durch Anforderungen aus dem XQuery-Umfeld weiterentwickelt. Und auch die W3CArbeitsgruppe zu XSLT hatte eine Reihe von Erweiterungswünschen zum von XSLT genutzten XPath. Die XSLT- und XQuery-Anforderungen bildeten dann die Grundlage für die Version 2.0 von XPath, die somit zum zentralen Bestandteil von XQuery 1.0 geworden ist. Der beste „Beweis“ für diese enge Verzahnung zwischen XQuery 1.0 und XPath 2.0 ist die Tatsache, dass beide W3C-Standards auf einem gemeinsamen Datenmodell beruhen [XQDM]. Nach Vorlage des ersten Entwurfs der XQuery-Spezifikation im Jahre 2001 begann eine ausführliche und damit auch zeitaufwändige Diskussion über die endgültige Form des Standards. Die Ankündigung „Verabschiedung des XQuery-Standards steht kurz bevor“ war auf Konferenzen und WebDiskussionsgruppen zwar häufig zu hören, die endgültige Verabschiedung zog sich aber recht lange hin. Zum Zeitpunkt der Erstellung dieses Buches in der Mitte des Jahres 2004 lag immer noch keine endgültige Verabschiedung des XQuery-Standards vor. Die im November 2003 veröffentlichte Version kann allerdings als sehr stabil angesehen werden und wird aller Voraussicht nach – abgesehen von kleineren Änderungen und Umformulierungen – als W3C Recommendation übernommen werden. Auf der Basis der November 2003-Spezifikation existiert bereits eine Vielzahl von Veröffentlichungen und Implementierungen. Auch die Beispiele des vorliegenden Buches beruhen auf dieser Version des XQuery-Standards. Abweichungen vom kurz vor der Verabschiedung stehenden offiziellen Standard XQuery 1.0 sind zwar unwahrscheinlich, aber natürlich nicht völlig auszuschließen. Wenn Sie also die Beispiele dieses Buches mit einer XQuery-Implementierung nutzen, die nicht auf der November 2003-Spezifikation, sondern auf einer späteren Version des Standards beruht, und bei diesem Einsatz Inkonsistenzen gegenüber den Angaben in diesem Buch auftreten sollten, so könnte die Ursache in unmittelbar vor der Verabschiedung aufge18
Einführung
nommenen Änderungen liegen. Nicht nur in diesem Fall lohnt sich ein Blick auf die Webseite dieses Buches, wo Sie in diesen Fällen Updates zu den Beispielen finden werden (http://www.entwickler.com/buecher/xquery). Mit der Verabschiedung der XQuery 1.0-Version ist die Entwicklung von XQuery aber sicherlich noch nicht abgeschlossen. Im Vorgriff auf das abschließende Kapitel dieses Buches, in dem die Vor- und Nachteile der ersten XQuery-Version diskutiert werden, sei an dieser Stelle bereits auf zwei Features verwiesen, die zum Teil aus Komplexitätsgründen und daher mit der Zielsetzung, die Verabschiedung der ersten Version nicht noch weiter nach hinten zu verschieben, von der W3C-Arbeitsgruppe nicht in Version 1.0 aufgenommen wurden. Es handelt sich dabei um Volltext-Suchfunktionen und Update-Möglichkeiten. Insbesondere der Verzicht auf Update-Möglichkeiten hat einerseits in ersten Beurteilungen von XQuery zu Kritik geführt. Andererseits wurden einige der zum derzeitigen frühen Zeitpunkt bereits verfügbaren Implementierungen (s. Kapitel 3) um herstellerspezifische Erweiterungen beim Thema Updatemöglichkeiten ergänzt. Anlass für solche Erweiterungen war sicherlich auch der Blick auf die „Konkurrenz“ SQL. Ein SQL ohne Update-, Insert- und DeleteFunktionen, also ein reines Read-Only-SQL ist eigentlich kaum vorstellbar bzw. nur in einer weitaus geringeren Zahl von Projekten einsetzbar. Analog wird auch XQuery in zukünftigen Versionen nicht nur an dieser Stelle erweitert werden. Veröffentlichungen der Mitglieder der W3C-Arbeitsgruppe zeigen, dass dieses „Problem“ erkannt wurde und daher mit einer Weiterentwicklung des Standards zu rechnen ist.
1.3.2 Anforderungen Eines der ersten Dokumente, die die W3C-Arbeitsgruppe zum Thema XQuery veröffentlicht hat, war mit [XQR] eine Zusammenstellung der Anforderungen an die neu zu definierende Sprache. Neben einigen Anforderungen an die Sprache selber (wie z.B. eine für Menschen lesbare Syntax, Deklarativität und Protokollunabhängigkeit) sind dort u.a. auch folgende erwartete Einsatzgebiete für die Sprache aufgelistet: • Verarbeitung aller Arten von XML-Dokumenten. Zu unterscheiden sind dabei datenorientierte und dokumentenorientierte XML-Dokumente. 19
Standardisierung
• • •
Während datenorientierte XML-Dokumente meist aus relational gespeicherten Daten erzeugt werden und daher eine klare Struktur aufweisen, kann man dokumentenorientierte Dokumente eher als „Freitext in XMLFormat“ kennzeichnen. Aber auch Mischformen zwischen diesen beiden Typen sind möglich: Bei solchen hybriden XML-Dokumenten liegt meist ein „Header-Body-Aufbau“ vor, in dem nach einem klar strukturierten Teil im Header des Dokumentes ein weniger strukturierter Teil folgt. Beispiele für solche Mischformen sind Börsenberichte, bei denen zunächst nach einem festgelegten Muster die relevanten Informationen zur untersuchten Aktie (Name, WKN, aktueller Kurs etc.) angegeben sind, bevor dann in „Freiformat“ die eigentliche Nachricht aufgelistet wird. Verarbeitung von Konfigurationsdateien, bei denen sich XML als Datenformat durchgesetzt hat. Filterung von Datenströmen analog zur UNIX-Filterverarbeitung z.B. bei größeren Logging-Datenströmen. Abfragen auf DOM (Document Object Model)-Strukturen
Neben diesen Anforderungen an die zu verarbeitenden Inputdaten sollte XQuery auch möglichst unabhängig von der Systemumgebung sein. Eine XQuery-Abfrage innerhalb einer URL oder einer JSP-Seite sollte genauso möglich sein wie die Einbindung in Programmiersprachen.
1.3.3 Andere XML-Standards Bereits im einführenden Kapitel 1.1 wurde die enge Verknüpfung von XQuery mit weiteren (XML-)Standards erwähnt. Dies ist natürlich kein Zufall, sondern bewusst aufgrund der breiten Standard-Abdeckung des gesamten XML-Bereiches erfolgt. Die enge Verzahnung wurde u.a. dadurch erreicht, dass die W3C-Arbeitsgruppen, die sich mit der Erstellung der Weiterentwicklung ähnlicher Standards befassen, gemeinsame Sitzungen mit der XQuery-W3C-Arbeitsgruppe durchgeführt haben. Auf diese Weise konnten die gegenseitigen Anforderungen bei der (Weiter-)Entwicklung der XMLStandards berücksichtigt werden.
20
Einführung
Neben den grundlegenden XML-Standards, in denen die XML-Syntax und die Semantik festgelegt wurden, sind für XQuery vor allem die folgenden drei Standards relevant: • XPath • XML-Schema • XSLT Dabei ist vor allem XPath in Version 2.0 so eng mit XQuery verwandt, dass ein XQuery-Neueinsteiger, der sich bereits mit XPath 2.0 beschäftigt hat, in kürzester Zeit die zusätzlichen XQuery-Features lernen kann. Schätzungen zufolge besteht XQuery 1.0 zu 80% aus XPath 2.0, da die Selektion, Navigation und Auswahl von XML-Fragmenten aus Inputdaten über XPath-Features erfolgt und somit die zentrale Komponente von XQuery darstellt. Abbildung 1.1 zeigt die Verzahnung der drei XML-Standards. XPath 2.0 bildet die Grundlage sowohl für XSLT als auch für XQuery. Wie in Kapitel 2.4 noch genauer erläutert wird, bietet eine XML-Schema-Definition die Möglichkeit, benutzerdefinierte Datentypen innerhalb von XQuery-Anfragen zu verwenden.
Abbildung 1.1: Abhängigkeiten der XML-Standards
21
Standardisierung
XPath XPath wurde im Jahr 1999 durch das W3C verabschiedet und ist eine Sprache zur Lokalisierung von Teilen eines XML-Dokumentes. XPath wird in einer Vielzahl von XML-Standards und Tools eingesetzt und ist vergleichbar mit den Regulären Ausdrücken, mit denen in der Nicht-XML-Welt bestimmte Konstrukte innerhalb von Textdateien gesucht werden können. XPath arbeitet auf einer Baumansicht eines XML-Dokumentes. Dabei werden die folgenden sieben Knotentypen unterschieden: • Wurzelknoten: ein virtueller Knoten, der nicht aus dem zugrunde liegenden Dokument entnommen ist und als Einstiegspunkt in das Dokument dient • Elementknoten • Attributknoten • Textknoten für Text innerhalb von Elementen • Namensraumknoten, falls entsprechende Namensraumangaben im Dokument vorliegen • Verarbeitungsanweisungsknoten • Kommentarknoten Ein XPath-Ausdruck besteht aus einer Folge von Lokalisierungsschritten. Jeder Lokalisierungsschritt selektiert dabei eine Teilmenge der Knoten eines Dokumentes. Diese Ergebnismenge eines Lokalisierungsschrittes ist dann der Ausgangspunkt für den nächsten Lokalisierungsschritt. Entsprechend den Angaben des nächsten Lokalisierungsschrittes wird – ausgehend von der Knotenmenge, die beim vorhergehenden Lokalisierungsschritt ermittelt wurde – eine neue Knotenmenge selektiert. In Abhängigkeit der beim Lokalisierungsschritt verwendeten Achsenangaben kann die selektierte Knotenmenge dabei auch größer werden. Syntaktisch sieht ein Lokalisierungsschritt wie folgt aus: Achse::Knotentest[Prädikate]
Er besteht aus den folgenden drei Bestandteilen: • Achse: gibt die Richtung an, in der die neu zu selektierenden Knoten ausgehend von der Ausgangs-Knotenmenge gesucht werden sollen. 22
Einführung
• •
Knotentest: Einschränkung der durch die Achsenangabe erreichbaren Knoten durch Angabe von geforderten Knotennamen oder Knotentypen (z.B. comment() als Angabe für Kommentarknoten). Prädikate: Über Prädikate können optional weitere Filterbedingungen angegeben werden. Dazu werden XPath-Ausdrücke benutzt, aus denen für jeden über Achse und Knotentest selektierten Knoten ein booleanWert ermittelt wird, der über die Aufnahme des betreffenden Knotens in die Ergebnismenge des Lokalisierungsschrittes entscheidet. Verwendet werden können in solchen Ausdrücken auch XPath-eigene Funktionen. Neben String-Funktionen (concat(), substring(),…) und BooleanFunktionen ( contains(), not(), …) stellt XPath auch Funktionen bereit, die sich mit der Ordnung innerhalb von XML-Dokumenten beschäftigen (position(), last(), …).
Über die Angabe einer Achse wird ausgehend von einem Kontextknoten (also dem Ergebnisknoten des vorherigen Lokalisierungsschrittes) eine bestimmte Menge von Knoten für den nächsten Schritt adressiert. In einer Folge von Lokalisierungsschritten kann es sich auch um eine Menge von Kontextknoten handeln. In diesem Fall wird der durch die Achse festgelegte Schritt für jeden Knoten dieser Knotenmenge durchgeführt und anschließend zu einer Knotenmenge zusammengefügt, für die dann die weiteren Bestandteile des Lokalisierungsschrittes (Knotentest und optionale Prädikate) angewendet werden. Folgende Achsen können innerhalb von Lokalisierungsschritten angegeben werden: • self: Selektiert den Kontextknoten selber • child: alle Kinder des Kontextknotens. Attribut- und Namensraumknoten sind im Sinne dieser Achse keine Kinder eines Knotens. Für den Zugriff auf Attribut- oder Namensraumknoten existieren die folgenden beiden Achsenangaben. • attribute: Selektiert alle Attributknoten des Kontextknotens • namespace: Selektiert alle Namensraumknoten des Kontextknotens • parent: der Elternknoten des Kontextknotens • descendant: selektiert alle Nachkommen in der Baumdarstellung, also die Kinder, deren Kinder usw. 23
Standardisierung
• • • •
• •
•
descendant-or-self: selektiert alle Nachkommen inklusive des Kontextknotens ancestor: selektiert alle Vorgänger in der Baumdarstellung, also den Elternknoten sowie rekursiv alle weiteren Elternknoten bis zum Wurzelknoten ancestor-or-self: selektiert alle Vorgänger inklusive des Kontextknotens following: alle Nachfolger in der Dokumentreihenfolge. Zu beachten ist also der Unterschied zwischen den über die Achse descendant selektierten Nachfolgern in der Baumdarstellung und den über following selektierten Nachfolgern in der Dokumentdarstellung, d.h. following selektiert alle Knoten, die im zugrunde liegenden XML-Dokument nach dem Kontextknoten aufgelistet sind. following-sibling: alle nachfolgenden Geschwisterknoten in der Dokumentreihenfolge. Geschwisterknoten sind Knoten, die denselben Elternknoten besitzen. preceding: alle Vorgänger in der Dokumentreihenfolge. Zu beachten ist auch hier der Unterschied zwischen den über die Achse ancestor selektierten Vorgängern in der Baumdarstellung und den über preceding selektierten Vorgängern in der Dokumentdarstellung. preceding-sibling: alle vorhergehenden Geschwisterknoten in der Dokumentreihenfolge.
Für einige dieser Achsen existieren Abkürzungen, die in der Regel innerhalb von XPath-Beispielen zu finden sind, z.B. • child:: kann komplett entfallen • attribute:: kann durch ein @-Zeichen abgekürzt werden • descendant-or-self:: kann durch // abgekürzt werden Das folgende Beispiel zeigt die Navigation und Selektion innerhalb von XML-Dokumenten über XPath-Ausdrücke. Abbildung 1.2 zeigt eine vereinfachte Baumdarstellung des folgenden XML-Dokumentes:
24
Einführung Schmitz Hauptstrasse 12345 Entenhausen Meier Schlossallee 99999 XYZ-Stadt Turmstrasse 11111 ABC-Dorf Mueller
[email protected]
25
Standardisierung
Abbildung 1.2: Baumdarstellung eines XML-Dokumentes
Anhand des folgenden XPath-Ausdrucks soll nun die Vorgehensweise bei der Auswertung von XPath-Ausdrücken illustriert werden: /child::Personenliste/child::Person[Name="Mueller"]/ preceding::Adresse/child::Plz
bzw. in abgekürzter Schreibweise /Personenliste/Person[Name="Mueller"]/preceding::Adresse/ Plz
Dieser XPath-Ausdruck besteht aus vier Lokalisierungsschritten. Die Ergebnismenge des ersten Schrittes /child::Personenliste
besteht aus dem (einzigen) Personenliste-Knoten. Ausgehend von dieser einelementigen Knotenmenge werden über den zweiten Schritt /child::Person[Name="Mueller"]
26
Einführung
zunächst unter den Kindern (Achse = child) dieses Knotens alle Knoten mit Namen Person (Knotentest = Person) ausgewählt. Dies wären also eigentlich alle drei Person-Elemente direkt unterhalb der Personenliste. Durch die zusätzliche Angabe eines Prädikates – in diesem Fall durch die Filterbedingung Name="Mueller" – wird diese zunächst dreielementige Knotenmenge auf eine einelementige Menge reduziert. Diese ist in Abbildung 1.3 schraffiert gekennzeichnet und stellt die Ergebnismenge des zweiten Lokalisierungsschrittes dar.
Abbildung 1.3: XPath-Navigation (1)
Der dritte Lokalisierungsschritt /preceding::Adresse
geht nun von dieser in Abbildung 1.3 schraffiert gekennzeichneten einelementigen Knotenmenge aus und selektiert über die preceding-Achse zunächst alle in Dokumentreihenfolge vorhergehenden Knoten. Dies sind also alle in Abbildung 1.3 gestrichelt umrandeten Knoten. Über die KnotentestAngabe Adresse werden daraus nun alle Adresse-Knoten ausgewählt. Da in diesem Lokalisierungsschritt kein optionales Prädikat zur weiteren Ein-
27
Standardisierung
schränkung der Knotenmenge angegeben ist, besteht die Ergebnismenge dieses dritten Lokalisierungsschrittes also aus den drei in Abbildung 1.4 schraffiert gekennzeichneten Adresse-Knoten. Dieser dritte Lokalisierungsschritt ist also ein Beispiel dafür, dass sich die selektierte Knotenmenge durch einen weiteren Schritt auch vergrößern lässt.
Abbildung 1.4: XPath-Navigation (2)
Abschließend werden ausgehend von dieser Knotenmenge über den letzten Lokalisierungsschritt /child::Plz
unter allen Kinderknoten dieser drei Adresse-Knoten noch alle PLZ-Knoten selektiert. Ergebnis des gesamten XPath-Ausdruckes /child::Personenliste/child::Person[Name="Mueller"]/ preceding::Adresse/child::Plz
bzw. in Kurzform /Personenliste/Person[Name="Mueller"]/preceding::Adresse/ Plz 28
Einführung
ist also die in Abbildung 1.5 schraffiert gekennzeichnete Knotenmenge mit drei PLZ-Knoten.
Abbildung 1.5: XPath-Navigation (3)
Weitere Beispiele für XPath-Ausdrücke folgen in Kapitel 2 bei der Vorstellung der XQuery-Sprachbestandteile. XPath in der Version 1.0 kennt nur vier Datentypen: •
• • •
boolean node-set (Knotenmenge) number string
Eine der für XQuery wichtigen Erweiterungen in XPath 2.0, das die Grundlage für XQuery 1.0 bildet, ist eine Erweiterung dieses Typkonzeptes u.a. durch die Möglichkeit, über XML-Schema definierte Datentypen zu verwenden. XPath selber ist aber noch keine XML-Abfragesprache, da zwar die Selektion von XML-Fragmenten möglich ist, nicht aber die Kombination mehrerer Fragmente zu einer Ergebnismenge. An dieser Stelle setzt dann XQuery an und erweitert die durch XPath 2.0 verfügbaren Selektionsmöglichkeiten entsprechend. 29
Standardisierung
XSLT Wie bereits mehrfach erwähnt, hat sich XML vor allem als Standard im Bereich Datenaustauschformate etabliert. Zwischen verschiedenen Anwendungen, aber auch über Unternehmensgrenzen hinweg werden häufig XMLFormate in Form von XML-Schema-Definitionen entwickelt, die dann zur Integration der unterschiedlichsten Systeme eingesetzt werden. Nicht immer ist ein auf diese Art definiertes XML-Format aber exakt das, was innerhalb der Anwendungen benötigt wird. Gesucht ist also häufig eine Möglichkeit, aus einem anwendungsspezifischen Format das erforderliche XML-Format zu generieren oder umgekehrt. Dabei muss es sich bei dem anwendungsspezifischen Format nicht zwingend auch um ein XML-Format handeln. Auch andere Textformate wie z.B. HTML, WML oder ein ASCIIFormat sind denkbar.
Abbildung 1.6: XSLT
Für die Transformation von einem XML-Format in ein anderes XML-Format bzw. in ein anderes Textformat kann XSLT eingesetzt werden. Die Vorgehensweise bei einer XSLT-Transformation zeigt Abbildung 1.6. Die für die Transformation benötigten Regeln – also Aussagen darüber, welche Inhalte aus dem Input-Dokument in welcher Formatierung im Output-Dokument
30
Einführung
auftauchen sollen – enthält die XSLT-Stylesheet-Datei, die wiederum als XML-Dokument spezifiziert wird. Das folgende Beispiel zeigt ein minimales Stylesheet:
Dieses Stylesheet enthält unterhalb des Wurzelelementes transform aus dem Namensraum http://www.w3.org/1999/XSL/Transform keine Umwandlungsregeln, d.h. Input-Dokumente werden im Prinzip1 unverändert ausgegeben. Transformationsregeln werden in Form von Schablonen angegeben. Jede Schablone ist gekennzeichnet durch ein template-Element, bei dem über das Attribut match ein XPath-Ausdruck angegeben werden muss, der diejenigen Bestandteile des Inputdokumentes selektiert, die transformiert werden sollen. Das folgende Beispiel enthält genau eine Transformationsregel. 30.00) or $b/publisher = "Addison-Wesley")
verkürzt das Ergebnis daher auf Tomcat 4x
If-then-else Das nächste Beispiel illustriert den Einsatz einer if-then-else-Konstruktion in der Return-Klausel eines XQuery-Ausdruckes: let $input := doc("input/bib.xml") let $schnitt := avg($input//book/price) return { for $b in $input/bib/book return if( xs:decimal($b/price) < $schnitt) then { string($b/title) } else if ( xs:decimal($b/price) < 1.2*$schnitt ) then { string($b/title) } else
70
Sprachbestandteile
{ string($b/title) } }
Die avg-Funktion ist eine vordefinierte XQuery-Funktion zur Durchschnittsbildung. In Kapitel 2.5.2 werden vordefinierte XQuery-Funktionen behandelt. Das Ergebnis dieser Abfrage sieht wie folgt aus: Java Persistenz Strategien Oracle, Java, XML Tomcat 4x Refactoring
2.3.2 Arithmetische Operatoren Die folgenden bekannten arithmetischen Operatoren können in XQueryAusdrücken verwendet werden: • • •
• • •
+ * div (Floating-Point-Division) idiv (ganzzahlige Division) mod (Modulo-Operation)
Zusätzlich existieren noch die folgenden vordefinierten XQuery-Funktionen: • abs (Absoluter Wert) • avg (Durchschnittswert) • ceiling (Aufrundung auf den nächsthöheren ganzzahligen Wert) • floor (Abrundung auf den nächstniedrigeren ganzzahligen Wert) • min (Berechnung des Minimums) • max (Berechnung des Maximums) 71
Operatoren
•
round und round-half-to-even (Rundung zum nächsten IntegerWert)8 sum (Berechnung der Summe)
•
2.3.3 Vergleichs-Operatoren XQuery unterstützt die bekannten Vergleichsoperatoren • = • != • < • • >= Zu beachten ist aber ein wichtiger Unterschied zwischen Wertevergleichen und allgemeinen Vergleichen. Wertevergleiche erfordern mehr Typgenauigkeit als allgemeine Vergleiche. Während bei Wertevergleichen die Datentypen der beiden zu vergleichenden Objekte gleich sein müssen, können bei allgemeinen Vergleichen über die aufgeführten Operatoren auch Sequenzen mit atomaren Werten verglichen werden. Die folgenden beiden Abschnitte enthalten Beispiele, die diesen Unterschied verdeutlichen.
8
Der Unterschied zwischen den beiden Methoden besteht darin, auf welchen
Wert gerundet wird, falls zwei Werte gleich weit vom Ursprungswert entfernt liegen: Die round-Funktion rundet in diesem Fall immer zum nächsthöheren Wert, die round-half-to-even-Funktion zum nächstgelegenen geraden Wert. Beispiel: round(2.5) = 3; round-half-to-even(2.5) = 2. Bei der round-half-toeven-Funktion kann über einen optionalen Parameter zusätzlich noch die Stelle angegeben werden, auf die die Rundungsoperation angewendet werden soll. 72
Sprachbestandteile
Allgemeine Vergleiche Das erste Beispiel zu einem allgemeinen Vergleich selektiert Bucheinträge anhand der Vor- und Nachnamen von Autoren. for $b in doc("input/bib.xml")/bib/book where $b/author/last = "Wolff" and $b/author/first = "Andreas" return { $b/title } { $b/author }
Das Ergebnis sieht wie folgt aus, ist allerdings vermutlich nicht das, was mit dieser Abfrage eigentlich erreicht werden sollte: Java Persistenz Strategien Holubek Andreas Jansen Rudolf Munsky Robert Wolff Eberhard
73
Operatoren
Wenn mit obiger Anfrage wirklich alle Bücher mit einem Autor “Andreas Wolff” gesucht werden sollten, dann ist dieses Ergebnis nicht das gewünschte. Die entscheidende Stelle in diesem Zusammenhang ist die where-Klausel where $b/author/last = "Wolff" and $b/author/first = "Andreas"
Die beiden XPath-Ausdrücke /author/last und /author/first werden zwar in jeder Iteration der for-Schleife für die identische Belegung der Variablen b bearbeitet. Es ist aber nicht sichergestellt, dass in beiden XPathAusdrücken auch dasselbe -Element bearbeitet wird. Wie man am Ergebnis der Abfrage erkennen kann, gibt es in den Inputdaten ein Buch mit einem Autor, der den Nachnamen „Wolff“ besitzt, und einen weiteren Autor mit Vornamen „Andreas“. Dieses Buch bzw. diese Belegung der Variablen b erfüllt also beide XPath-Bedingungen und wird daher über die ReturnKlausel ausgegeben. Um nun tatsächlich alle Bücher mit einem Autor „Andreas Wolff“ ermitteln zu können, muss also gewährleistet werden, dass sich die beiden XPathAusdrücke auf denselben Autor beziehen. Eine Möglichkeit dazu ist die folgende: for $b in doc("input/bib.xml")/bib/book, $a in $b/author where $a/last = "Wolff" and $a/first = "Andreas" return { $b/title }
Hier werden zwei for-Schleifen geschachtelt aufgerufen. Eine andere Schreibweise der for-Klausel, die diese Verschachtelung besser verdeutlicht, ist die folgende: for $b in doc("input/bib.xml")/bib/book for $a in $b/author ... 74
Sprachbestandteile
Für jedes Buch bzw. jedes -Element wird nun explizit jeder Autor bzw. jedes -Element durchlaufen. Somit ist sichergestellt, dass die folgenden beiden XPath-Ausdrücke auf demselben -Element operieren. Als Folge dieser Umstellung werden nun wirklich nur diejenigen Bücher angezeigt, die einen Autor mit Vornamen „Andreas“ und Nachnamen „Wolff“ besitzen. Da es einen solchen Eintrag in den Inputdaten nicht gibt, ist das Ergebnis dieses XQuery-Ausdrucks also leer. Ein weiteres Beispiel, das die Auswertung von Vergleichsoperationen verdeutlichen soll, ist das folgende: { let $b:=doc("input/bib.xml")/bib/book where $b/@year = 2002 return { $b/title } }
Der Variablen $b wird in diesem Beispiel einmalig eine Sequenz mit allen -Elementen aus den Inputdaten zugewiesen. Für diese Gesamtsequenz ist der Filterausdruck where $b/@year = 2002
erfüllt, da es in der Sequenz ein Buch mit Erscheinungsjahr 2002 gibt. Somit wird in der Return-Klausel der XPath-Ausdruck $b/title
für die gesamte Sequenz ausgewertet, was schließlich zu folgendem Ergebnis führt:
75
Operatoren Java Persistenz Strategien Oracle, Java, XML Tomcat 4x Refactoring
Der entscheidende Punkt in diesem Vergleich ist also die Tatsache, dass im Filterausdruck where $b/@year = 2002
eine Sequenz auf der linken Seite mit einem atomaren Wert auf der rechten Seite verglichen wird und dieser Vergleich bei Verwendung eines allgemeinen Vergleichoperators genau dann erfüllt ist, wenn es in der Sequenz mindestens einen Wert gibt, der dem atomaren Wert auf der rechten Seite entspricht. Die wahrscheinlich beabsichtigte Ausfilterung aller Bücher mit einem Erscheinungsjahr ungleich 2002 könnte beispielsweise durch Austausch der Let-Klausel gegen eine For-Klausel wie folgt erreicht werden: { for $b in doc("input/bib.xml")/bib/book where $b/@year = 2002 return { $b/title } }
76
Sprachbestandteile
Über allgemeine Vergleichsoperatoren können aber nicht nur Sequenzen mit atomaren Werten verglichen werden, sondern auch Sequenzen untereinander. In dieser Konstellation liefert der allgemeine Vergleichsoperator = den Wert true, falls es mindestens einen Wert in der linken Sequenz gibt, dessen Vergleich mit mindestens einem Wert aus der rechten Sequenz den Wert true ergibt. Oder anders formuliert: Zwei Sequenzen werden bei einem allgemeinen Vergleich als gleich betrachtet, wenn ihre Schnittmenge nicht leer ist. Zur Illustration dient das folgende Beispiel: let $books := doc("input/bib.xml")/bib/book for $b in $books, $c in $books where $b/author = $c/author and $b/title != $c/title return { $b/title } { $c/title }
Hier werden alle Bücher gesucht, die einen gemeinsamen Autor haben. Aufgrund der beschriebenen Regel zur Auswertung von allgemeinen Vergleichen zweier Sequenzen kann dies über den Vergleich $b/author = $c/author
erfolgen, der den Wert true ergibt, falls die Autorenliste von $b mindestens einen Autor enthält, der auch in der Autorenliste von $c vorkommt. Wären nur diejenigen Bücher gesucht, bei denen alle Autoren gleich sind, so müsste der zugehörige Wertevergleichsoperator eq eingesetzt werden, der im folgenden Abschnitt vorgestellt wird. Das Ergebnis der Abfrage mit dem allgemeinen Vergleichsoperator = lautet: Java Persistenz Strategien Oracle, Java, XML 77
Operatoren Java Persistenz Strategien Tomcat 4x Oracle, Java, XML Java Persistenz Strategien Tomcat 4x Java Persistenz Strategien
Wertevergleiche Da innerhalb von XQuery- bzw. XML-Anwendungen durchaus mehrere verschiedene Vergleichsverfahren benötigt werden, gibt es neben den im vorigen Abschnitt beschriebenen allgemeinen Vergleichen über die Operatoren • = • != • < • • >= noch die folgenden sechs weiteren Operatoren, die Wertevergleiche durchführen: • eq (Test auf Gleichheit) • ne (Test auf Ungleichheit) • lt (Kleiner-Test) • le (Kleiner-oder-Gleich-Test) • gt (Größer-Test) • ge (Größer-oder-Gleich-Test)
78
Sprachbestandteile
Diese Wertevergleichsoperatoren erfordern eine höhere Typgenauigkeit in zweierlei Hinsicht: 1. Ein Vergleich einer mehrelementigen Sequenz mit einem atomaren Wert ist nicht erlaubt und erzeugt daher eine entsprechende Fehlermeldung. 2. Die Datentypen der beiden zu vergleichenden Objekte müssen übereinstimmen. Die folgenden beiden Beispiele zeigen jeweils einen fehlerhaften Einsatz des Wertevergleichs-Operators eq. Zunächst wird das zweite Beispiel aus dem vorigen Abschnitt umgestellt von einem allgemeinen Vergleich über den Operator = auf einen Wertevergleich mit dem Operator eq: { let $b:=doc("input/bib.xml")/bib/book where $b/@year eq 2002 return { $b/title } }
Der Wertevergleich $b/@year eq 2002
verstößt gegen die erste oben aufgeführte Regel, da über den XPathAusdruck $b/@year
eine Sequenz generiert wird, die bei einem Wertevergleich nicht mit dem atomaren Wert 2002 verglichen werden darf. Die genaue Fehlermeldung hängt von der eingesetzten XQuery-Implementierung ab. Die Implementierung IPSI (s. Kapitel 3.2.1) gibt folgende Fehlermeldung aus:
79
Operatoren Unexpected parameter type "2004 2003 2002 1999" for function "http://www.w3.org/TR/xquery-semantics:eq" expected was http://www.w3.org/2001/XMLSchema:NOTATION
Eine Korrektur dieses Fehlers ist möglich, indem aus der mehrelementigen Sequenz auf der linken Seite ein einzelner Wert extrahiert wird. In dem korrigierten Beispiel { let $b:=doc("input/bib.xml")/bib/book where $b[1]/@year eq 2002 return { $b/title } }
wird über den XPath-Ausdruck $b[1]/@year
nur das Erscheinungsjahr des ersten -Elementes in den eq-Vergleich einbezogen. Aber auch dieser Ausdruck ist noch fehlerhaft, da er gegen die zweite Wertevergleichs-Regel verstößt. In XQuery-Ausdrücken ohne zugrunde liegende XML-Schema-Definition erfolgt für typlose Ausdrücke bei Wertevergleichen eine Typkonvertierung auf einen String-Wert. Im vorliegenden Beispiel ohne XML-Schema-Definition wird also das Attribut year als String behandelt. Demzufolge liegt in der Where-Klausel where $b[1]/@year eq 2002
ein Wertevergleich zwischen einem String-Wert und einem numerischen Wert vor, also ein Verstoß gegen die zweite oben aufgeführte Regel bei Einsatz von Wertevergleichen.
80
Sprachbestandteile
Eine Korrektur dieses Fehlers durch eine explizite String-Angabe der Jahreszahl 2002 ergibt nun einen fehlerfrei ausführbaren Ausdruck { let $b:=doc("input/bib.xml")/bib/book where $b[1]/@year eq "2002" return { $b[1]/title } }
der allerdings ein leeres Element
als Ergebnis liefert, da das erste -Element in der Inputdatei ein anderes Erscheinungsjahr besitzt. Im Gegensatz zu diesem Wertevergleich über den eq-Operator wäre ein allgemeiner Vergleich des Attributes year mit einem numerischen Wert über den =-Operator erlaubt gewesen: where $b[1]/@year = 2002
Bei allgemeinen Vergleichen zwischen einem oder zwei Objekten ohne Typinformation wird dieser Vergleich nach den folgenden Regeln durchgeführt: • Hat ein Objekt keinen Typ und das andere einen numerischen Datentyp, so wird das typlose Objekt als double-Wert interpretiert (diese Regel ist in obigem Beispiel angewendet worden). • Haben beide keine zugrunde liegende Typinformation, so werden beide Objekte als string-Wert interpretiert. • In allen anderen Fällen wird der dynamische Typ des einen Objektes bestimmt (s. Kapitel 2.4) und anschließend das typlose Objekt ebenfalls auf diesen Wert gecastet. Falls dies nicht möglich ist, wird eine entsprechende Typumwandlungs-Fehlermeldung erzeugt. 81
Operatoren
Boolean-Werte Im Zusammenhang mit Vergleichsoperationen sind auch einige kurze Anmerkungen zum Boolean-Datentyp erforderlich. Dabei sind nämlich der XML-Schema-Datentyp boolean, der über die entsprechende NamespaceAngabe xs:boolean9 gekennzeichnet ist, sowie der so genannte Effective Boolean Value (EBV) eines Ausdruckes zu unterscheiden, der über die XQuery-Funktion boolean() ermittelt werden kann. Diese Funktion boolean() verhält sich allerdings nicht immer identisch zu einem Typcast auf xs:boolean, wie die folgenden Beispiele zeigen: let $a := () return { boolean(0), boolean(1), boolean(false()), boolean(""), boolean("false"), xs:boolean("false"), boolean($a) }
Der über die boolean()-Funktion ermittelbare EBV eines Wertes ist false genau dann, wenn eine der folgenden Regeln erfüllt ist: • Der Wert ist eine leere Sequenz. • Der Wert ist ein leerer String. • Es handelt sich um den xs:boolean-Wert false, der beispielsweise über die Funktion false() generiert werden kann.
9
Über das xs-Präfix wird der XML-Schema-Namespace
http://www.w3.org/2001/XMLSchema gebunden. 82
Sprachbestandteile
• •
Es handelt sich um den numerischen Wert 0. Es handelt sich um den double- oder float-Wert NaN10.
Ist keine dieser Regeln erfüllt, so liefert die Funktion boolean() den Wert true. Gemäß diesen Regeln ergibt die obige Abfrage mit den boolean() und xs:boolean()-Aufrufen die folgende Ausgabe: false true false false true false false
Dabei zeigen die beiden Aufrufe boolean("false") xs:boolean("false")
den wichtigen Unterschied zwischen diesen beiden Funktionen: Während bei der Bestimmung des EBV über die boolean()-Funktion der Inhalt des Strings nicht relevant ist (getestet wird bei String-Werten nur, ob diese leer sind oder nicht), ist für den Typcast mittels des xs:boolean-Aufrufes der Stringinhalt relevant. Der EBV des Strings „false“ ist also true, was bei Nichtbeachtung dieser Regel durch einen XQuery-Entwickler zu unerwarteten Effekten führen kann.
2.3.4 Reihenfolge-Operatoren Auch der Tatsache, dass die Reihenfolge von Knoten in XML-Inputdokumenten in Anwendungen und damit auch in Abfragen relevant sein 10
Der Wert NaN entspricht dem NULL-Wert für diese beiden Datentypen. 83
Operatoren
kann, wurde beim Design von XQuery Rechnung getragen. Über die beiden Operatoren • > kann ein Vergleich der Platzierung zweier Knoten in der Dokumentenreihenfolge vorgenommen werden. Über die folgende Abfrage sollen alle Buchtitel ausgegeben werden, die im Inputdokument vor dem ersten Buch mit Erscheinungsjahr 2002 aufgeführt sind. { let $bib := doc("input/bib.xml")/bib for $b in $bib/book where $b java -cp .;kawa-1.7.jar XQueryDemo return {$i}"
"for $i in (1,2,3)
Abfrage:for $i in (1,2,3) return {$i} Ergebnis:1, 2, 3
Die Qexo-Klassen stellen weitere Funktionen zur Ein- und Ausgabe von XQuery-Ausdrücken und deren Ergebnissen sowie zur Weiterverarbeitung dieser Ergebnisse zur Verfügung.
3.3.2 XQJ Während die herstellerspezifischen Lösungen zur Einbindung einer XQueryAbfrage in ein Java-Programm zwar in der Regel auf demselben Prinzip beruhen, unterscheiden sie sich aber so signifikant beispielsweise in Namenskonventionen, dass ein Einsatz eines unveränderten Sourcecodes in zwei verschiedenen Implementierungen nicht möglich ist. Genau diese Möglichkeit ist aber ein wichtiger Vorteil beim Einsatz von JDBC zur Anbindung von Java an relationale Datenbanken. JDBC für relationale Datenbanken Wie bereits mehrfach in diesem Buch sei auch an dieser Stelle wieder ein Vergleich der XML-Welt mit der Welt der relationalen Datenbanken erlaubt. Da sich SQL als Abfragesprache für relationale Datenbanken etabliert hat, war eine Einbindung von SQL-Ausdrücken in Java-Sourcecode einer der
147
Java-Anbindung
wichtigsten Bestandteile bereits in den ersten Java-Versionen. Auch wenn es mit SQLJ einen Standard gibt, der eine direkte Einbettung der SQLStatements in Java-Sourcecode ermöglicht, indem diese Statements vor dem eigentlichen Java-Compiler-Aufruf durch einen SQLJ-Precompiler vorverarbeitet und so in „normales“ Java-Format gebracht werden, war und ist JDBC für diese Aufgabe der am weitesten bekannte Standard. Inzwischen wird zwar insbesondere in großen Enterprise-Anwendungen meist JDBC nicht mehr direkt programmiert. Stattdessen gibt es beispielsweise mit JDO (Java Data Objects) oder EJB-CMP (Enterprise Java Beans – Container Managed Persistence)-Standards, die zwar auf JDBC aufbauen, dem Entwickler aber einen Großteil der manuellen Codierungsarbeit abnehmen. JDBC wird aber auch in Zukunft die Grundlage für eine JavaAnbindung an relationale Datenbanken bleiben. Einer der entscheidenden Vorteile von JDBC ist die Herstellerunabhängigkeit. Ein einfaches JDBC-Programm der folgenden Art ds = (DataSource) ctx.lookup("jdbc/Test_DB"); Connection conn = ds.getConnection(user, password); // Statement anlegen Statement stmt = conn.createStatement(); // Statement ausfuehren resSet = stmt.executeQuery("select bch_nr, bch_isbn, bch_titel from buch"); // Ergebnis ausgeben while (resSet.next()) { System.out.println("Nr:" + resSet.getInt(1)); System.out.println("ISBN:" + resSet.getString("bch_isbn")); System.out.println("Titel:" + resSet.getString(3)); } stmt.close(); 148
Implementierungen
kann problemlos19 mit den entsprechenden Produkten (JDBC-Treiber, Datenbank) unterschiedlicher Hersteller eingesetzt werden. Genau an dieser Stelle sieht man also unmittelbar einen der Unterschiede zu den im vorigen Abschnitt vorgestellten herstellerspezifischen Lösungen zur Einbindung von XQuery-Ausdrücken in Java-Anwendungen. Wenn XQuery also wirklich gemäß dem bereits mehrfach zitierten Werbeslogan „das SQL des 21. Jahrhunderts“ werden will, dann besteht an dieser Stelle noch erheblicher Nachholbedarf, denn viele Anwendungen werden in Java realisiert, sodass eine Abfragesprache zwingend auch ihre Stärken in Verbindung mit Java zum Ausdruck bringen muss. Diese derzeitige Schwäche von XQuery wurde bereits vor der offiziellen Verabschiedung der ersten XQuery-Version erkannt. Da trotz dieser Schwäche aber die grundlegende Bedeutung von XQuery für die XML-Welt außer Frage stand, haben sich mehrere Hersteller von XML-Produkten bzw. Technologien, die XML in immer stärkerem Maße unterstützen, zu einer Arbeitsgruppe zusammengeschlossen, die als JSR 225 XQJ entwickeln, eine Art „JDBC für XQuery“. XQJ für XML-Daten Zum Zeitpunkt der Erstellung dieses Buches liegt nur eine erste Early Draft Review-Version der XQJ-Spezifikation vor [XQJ]. Diese enthält aufgrund des frühen Status naturgemäß noch keine Details sowie keine Garantie, dass die endgültige Version sich nicht noch signifikant von dieser ersten Version unterscheidet. Trotzdem lässt sich an dem folgenden aus [XQJ] übernommenen Sourcecode-Auszug bereits die angestrebte Struktur von XQJ-Anwendungen und insbesondere die enge Anlehnung an die JDBC-Vorgehensweise erkennen: // establish a connection to the XQuery engine XQConnection conn = xqds.getConnection(); // create an expression object that is later used // to execute an XQuery expression 19
Probleme bei der Portierung entstehen in der Regel erst dann, wenn herstellerspezifische JDBC-Erweiterungen verwendet werden, die dann natürlich nicht ohne zusätzlichen Migrationsaufwand portiert werden können. 149
Java-Anbindung XQExpression expr = conn.createExpression(); // The XQuery expression to be executed String es = "for $n in fn:doc('catalog.xml')//item" + " return fn:data($n/name)"; // execute the XQuery expression XQResultSequence result = expr.executeQuery(es); // process the result (sequence) iteratively while (result.next()) { // retrieve the current item of the sequence as a // String String str = result.getString(); System.out.println("Product name: " + str); } // free all resources allocated for the result result.close(); // free all resources allocated for the expression expr.close(); // free all resources allocated for the connection conn.close();
Wie bei JDBC-Anwendungen soll auch bei XQJ-Anwendungen ein DataSource-Objekt – im obigen Beispiel das Objekt xqds – die Verbindung zur XML-Datenquelle kapseln. Die weiteren Schritte und Klassenbezeichnungen sollen an dieser Stelle nicht weiter beschrieben werden, sind aber bereits mit grundlegendem JDBC-KnowHow offensichtlich. Abbildung 3.4 zeigt die angestrebte Architektur von XQJ-Anwendungen. Aus einer Java-Anwendung heraus wird über XQJ-Funktionen ein XQueryAusdruck an eine XML-Datenquelle bzw. ein XQDataSource-Objekt übergeben. Dieses kapselt die XML-Datenquelle, die eine relationale Datenbank mit XML-Views, eine oder mehrere XML-Dateien oder jede andere Datenquelle sein kann, solange sie ihre Daten in XML-Format zur Verfügung stellt. Das Ergebnis des XQuery-Ausdruckes liegt in XML vor und kann mit den XQJ-Methoden in der Java-Anwendung verarbeitet werden. Ohne näher auf Details von XQJ eingehen zu wollen, lässt sich bereits anhand dieser ersten Public Draft Review-Version von [XQJ] das enorme Po150
Implementierungen
tenzial dieses kommenden Standards erkennen. Wenn dieser Standard konsequent weiterentwickelt und von den großen Herstellern unterstützt wird, steht einem Erfolg beim Einsatz von XQuery in Verbindung mit Java-Anwendungen eigentlich nichts mehr im Wege. Mit Interesse verfolgt werden sollte die Weiterentwicklung von XQJ unter anderem auch unter der Fragestellung, ob auch ein einziges DataSource-Objekt sowohl für XQuery-Abfragen auf XML-Daten als auch für SQL-Abfragen auf relationalen Datenbanken eingesetzt werden kann. Mit Hinblick auf die in Praxisprojekten häufig vorzufindende Koexistenz von XML- und relationalen Daten wäre diese Möglichkeit ein weiterer Meilenstein im Hinblick auf die Integration von XML- und relationaler Datenbank-Welt.
Abbildung 3.4: XQJ-Architektur
151
Anwendungen
4 Anwendungen Zum Abschluss dieses Buches folgen noch ein kurzes Kapitel über mögliche Anwendungen von XQuery sowie eine Zusammenfassung. Im Vergleich zu den vorigen Kapiteln über die Sprachentstehung, die einzelnen Sprachbestandteile sowie erste verfügbare Implementierungen ist dieses Kapitel das kürzeste. Der Grund dafür liegt darin, dass es zum derzeitigen frühen Zeitpunkt in der Entstehungsgeschichte der Sprache XQuery naturgemäß noch keine umfangreiche Liste von Erfolgsgeschichten in Form von Praxisprojekten geben kann, in denen XQuery bereits über einen längeren Zeitraum erfolgreich eingesetzt wurde. Stattdessen stellen die im Folgenden aufgeführten Anwendungsgebiete eher einen Blick in die Zukunft dar. In welchen Bereichen hat XQuery das Potenzial, produktiv eingesetzt zu werden? Neben den durchaus positiven Aussichten über mögliche Einsatzgebiete darf aber natürlich auch eine kritische Betrachtung der Probleme nicht fehlen, die mit einem XQuery-Einsatz verbunden sein können. Solche „Probleme“ werden in erster Linie durch fehlende Features auftreten. Zum derzeitigen frühen Zeitpunkt steht XQuery sicherlich noch nicht in der endgültigen Version zur Verfügung. Daher wird es sowohl beim Austesten als auch bei einem möglichen produktiven Einsatz von XQuery immer wieder Situationen geben, in denen der zur Verfügung stehende Sprachumfang nicht ausreichend sein wird. In dieser Hinsicht wird auch XQuery keine Sonderstellung einnehmen. Auch bei anderen Sprachen ist der derzeitig verfügbare Sprachumfang erst im Laufe der Zeit gewachsen. Als Beispiel sei hier die Sprache Java genannt, die zwar mit ihrer ersten Version bereits viele Freunde durch damals ganz neue Features (z.B. Plattformunabhängigkeit) gewinnen konnte. Heutige große Java-Projekte wären aber ausschließlich mit den bereits in Java 1.0 verfügbaren Sprachbestandteilen kaum vorstellbar.
153
Systemintegration
4.1
Systemintegration
XML als Datenaustauschformat zwischen Anwendungen spielt bereits heute eine wichtige Rolle im Bereich der Systemintegration. Aufgrund seiner Plattformunabhängigkeit bietet XML die Chance, innerhalb einer heterogenen Systemarchitektur mit Anwendungen, die auf verschiedenen Plattformen laufen und/oder in verschiedenen Sprachen implementiert wurden, ein von allen Systemen unterstütztes Datenformat zu definieren, über das sich die Systeme „unterhalten“ können. An den Schnittstellen der einzelnen Systeme wird dabei häufig die Aufgabe anfallen, interne Daten zu selektieren und gleichzeitig in das gemeinsame XML-Format zu transformieren – also eine Aufgabe, für die XQuery aufgrund seiner Abfrage- und Transformationsmöglichkeiten sehr gut geeignet ist. Im Rahmen einer solchen Systemintegration kann XQuery insbesondere seine Stärke ausspielen, auf unterschiedliche Inputdaten parallel zugreifen zu können. Wenn also Stammdaten in einer relationalen Datenbank vorliegen und die darauf basierenden dynamischen Daten in XML-Dateien bzw. XMLStreams vorliegen, so lassen sich beide Datenquellen in XQuery-Abfragen verbinden, falls für beide Quellen entsprechende XQuery-Inputadapter zur Verfügung stehen. Ein Problem bei dieser Konstellation und einer Vielzahl von zu verknüpfenden externen Datenquellen kann das Datentransfervolumen darstellen, falls die komplette Abfrage an einer Stelle, nämlich in der eingesetzten XQuery-Implementierung, vorgenommen werden muss. Für die Zukunft sind hier also sowohl bei der Weiterentwicklung des XQuerySprachstandards als auch bei der Erstellung von XQuery-Engines Ideen für eine verteilte Datenverarbeitung erforderlich.
4.2
Webanwendungen
Wie in Kapitel 3.3 bereits erwähnt, bieten die meisten derzeit schon verfügbaren XQuery-Implementierung eine Möglichkeit an, XQuery-Abfragen innerhalb von Java-Anwendungen einzusetzen. Ein Einsatzgebiet, in dem XQuery Chancen eingeräumt werden, sich als neuer Standard durchzusetzen, ist also die Integration von XML-Techniken in Java. Während dies derzeit noch über spezielle Java-APIs beispielsweise zur Verarbeitung von DOMStrukturen vorgenommen werden muss, wird XQuery hier spätestens dann 154
Anwendungen
ins Spiel kommen, wenn der in Kapitel 3.3.2 beschriebene XQJ-Standard als eine Art „JDBC für XQuery“ bzw. „JDBC für XML-Daten“ verabschiedet und von den wichtigsten Anbietern unterstützt wird. Ein weiteres Einsatzgebiet von XQuery ist der Einsatz in Form von Servlets. Auch hierzu bieten derzeit bereits einige Implementierungen Tools an. Die Qexo-Implementierung (s. Kapitel 3.2.2) ermöglicht beispielsweise über einen speziellen Parameter -servlet in der folgenden Form java –jar kawa-1.7.jar –xquery –servlet –C
eine Übersetzung eines XQuery-Skriptes in eine Servlet-Klasse, die dann über die bekannten Techniken beispielsweise in der Tomcat-Engine innerhalb von Webapplikationen genutzt werden kann. Auch im Webservice-Umfeld, in dem XML eine entscheidende Rolle spielt, sind Anwendungsgebiete für XQuery denkbar. Aber nicht nur in Form von Servlets oder innerhalb von WebserviceAnwendungen kann XQuery in Webapplikationen eingesetzt werden, sondern auch „hinter den Kulissen“ solcher Projekte bei der Auswertung von Logdateien. Immer mehr setzt sich nämlich der Trend durch, Logdateien im XML-Format anzulegen. Wer dort dann zwecks Fehlersuche oder Erstellung von Zugriffsstatistiken eine Abfrage auf diesen XML-Daten durchführen muss, wird sicherlich den Einsatz der XML-Abfragesprache XQuery in Erwägung ziehen. Eine weitere Möglichkeit besteht darin, nicht alle im XMLFormat aus diversen Applikationen ausgegebenen Logging-Informationen in Dateiform zu speichern, sondern über XQuery-Skripte online nur diejenigen Informationen auszufiltern, die tatsächlich relevant sind.
4.3
Fazit
Die aufgeführten Anwendungsgebiete machen XQuery also für die Zukunft sehr interessant. Bereits mehrfach sind in diesem Buch aber auch Kritikpunkte am aktuellen XQuery-Standard aufgeführt worden, die an dieser Stelle nochmals zusammengefasst werden sollen. Was fehlt also in XQuery 1.0 noch?
155
Fazit
•
• • •
Updatemöglichkeiten: Dies ist der in der Literatur am häufigsten genannte Kritikpunkt an der ersten XQuery-Version. Alle in diesem Buch aufgeführten Beispiele waren reine Read-Only-Beispiele. Es ist zwar über XQuery möglich, eigene Formate für die Konstruktion eines Abfrageergebnisses innerhalb der Return-Klausel zu verwenden. Eine Veränderung der Inputdaten dagegen ist nicht möglich. Von den Mitgliedern der W3C-XQuery-Arbeitsgruppe ist daher bereits verkündet worden, dass Update-Features ein zentraler Bestandteil der nächsten XQuery-Version 1.1 oder 2.0 werden sollen. Wenn XQuery wirklich innerhalb der XMLWelt eine ähnliche Bedeutung wie SQL in der relationalen Welt bekommen soll, so sind solche Update-Möglichkeiten auch zwingend erforderlich, denn wer kann sich schon ein reines Read-Only-SQL ohne Update-, Insert- und Delete-Befehl vorstellen? Fortgeschrittene Textoperationen, insbesondere Suchoperationen für den Einsatz von XML im Rahmen von Dokumentenverarbeitung. Ausführlichere Fehlerbehandlungsmöglichkeiten analog zu den trycatch-Blöcken in anderen Sprachen (s. Kapitel 2.8). Sicherheitsmechanismen, die spätestens dann benötigt werden, wenn XQuery in Praxisprojekten mit sensiblen Daten eingesetzt werden soll.
Zu hoffen bleibt, dass eine entsprechend erweiterte XQuery-Version möglichst bald zur Verfügung gestellt wird, da ansonsten die Gefahr besteht, dass jeder Anbieter einer XQuery-Implementierung hierzu eigene herstellerspezifische Erweiterungen einführt. Diese bringen das Problem, dass ein Austausch der eingesetzten XQuery-Implementierung mit entsprechend höherem Portierungsaufwand verbunden ist. Ein Beispiel dafür ist die bereits erwähnte Möglichkeit, XQuery-Ausdrücke in Java-Anwendungen zu nutzen. Dies bietet zwar inzwischen beinahe jede verfügbare Implementierung an, allerdings immer mit einer eigenen Syntax. Ein wichtiger Aspekt jeder neuen Sprache ist deren Komplexität und die damit verbundenen Schwierigkeiten beim Erlernen einer Sprache. Wenn Sie dieses Buch vollständig durchgearbeitet haben, dann haben Sie sicherlich bereits eine eigene Meinung zu der Frage, wie schwierig XQuery zu erlernen ist. Eine wichtige Rolle bei dieser Einschätzung spielen natürlich die Vorkenntnisse. Wer noch nie direkt mit XML gearbeitet hat, wird sicherlich
156
Anwendungen
mehr Zeit zur Einarbeitung in die „XML-Denkweise“ und damit auch in die XQuery-Vorgehensweise benötigen als jemand, der die zugrunde liegenden Techniken XPath und XML-Schema bereits kennt. Grundsätzlich lässt sich feststellen, dass XQuery natürlich die Komplexität dieser beiden zugrunde liegenden Standards erbt. Wer XQuery einsetzen will, sollte insbesondere die Möglichkeiten von XPath 2.0 kennen bzw. erlernen, denn Schätzungen zufolge besteht XQuery zu 80% aus XPath 2.0. Wer XQuery anwenden will und über entsprechende Grundkenntnisse in den vorgestellten XML-Standards verfügt, für den sollte das Erlernen der benötigten XQuery-Techniken kein unüberwindbares Hindernis darstellen. Richtig schwierig wird das Ganze eigentlich nur dann, wenn man selber eine XQuery-Implementierung erstellen will, denn dann führt kein Weg an einem intensiven Studium der zugrunde liegenden theoretischen Spezifikationen zum Datenmodell sowie der formalen Semantik vorbei. Bei der Abgrenzung gegenüber den anderen XML-Standards lässt sich feststellen, dass XQuery seine Stärken eher im Bereich XML-Datenverarbeitung hat, während XSLT mehr zur XML-Dokumentenverarbeitung eingesetzt wird. Mehrfach wurde in diesem Buch der Vergleich von XQuery mit SQL erwähnt. Wie am Anfang des Buches beschrieben, war eine der ersten Ideen bei der Entwicklung einer XML-Abfragesprache eine entsprechende Erweiterung von SQL. Auch wenn es solche Erweiterungen beispielsweise in Form des SQL/XML-Standards sowie weiterer herstellerspezifischer Features inzwischen gibt, so wurde aufgrund der grundlegend verschiedenen internen Struktur von XML- und relationalen Daten bewusst eine neue Sprache definiert. Wie vor allem im Kapitel über die FLWOR-Ausdrücke leicht zu erkennen ist, haben viele XQuery-Sprachbestandteile Ähnlichkeiten mit entsprechenden SQL-Features. Wie kann XQuery also im Vergleich zu SQL positioniert werden? Derzeit liegt SQL naturgemäß in Bedeutung und Marktanteilen noch weit vor XQuery. Der Grund dafür dürfte aber nicht darin liegen, dass SQL unbedingt
157
Fazit
besser als XQuery ist20, sondern weil der „Zielgruppenumfang“ sehr unterschiedlich ist: Die Menge von relational gespeicherten Daten als Zielgruppe von SQL ist derzeit in Praxisprojekten noch höher als die Zielgruppe XMLDaten für XQuery. Wie wird die IT-Welt aber in fünf oder zehn Jahren aussehen? Auch wenn ein solcher Zeitraum in der schnelllebigen IT-Welt ein nur schwer vorhersehbarer Zeitraum ist, so muss man sicherlich kein Prophet sein, um vorauszusagen, dass eine XML-basierte Datenübertragung und eine XML-basierte Daten- und Dokumentenspeicherung eine immer höhere Bedeutung erlangen und die relationale Speicherung sicherlich irgendwann überholen werden. Wenn XQuery sich als Standard für eine XML-Abfragesprache durchsetzt, dann wird XQuery spätestens zu diesem Zeitpunkt auch SQL als StandardAbfragesprache für Daten aller Art ablösen. Ist es also denkbar, dass Informatikstudenten in einigen Jahren standardmäßig zunächst in XQuery unterrichtet werden und der „alte Standard“ SQL nur noch in Spezialveranstaltungen eingesetzt wird? Werden reine SQL-Spezialisten also in mittlerer bis ferner Zukunft zu einer Minderheit gehören, die sich ausschließlich um die Pflege alter Anwendungen kümmern wird, die noch nicht auf den neuen Standard XQuery umgestellt worden sind? Antworten auf diese Fragen sollen und können an dieser Stelle natürlich (noch) nicht gegeben werden, denn Aussagen dazu wären zum Zeitpunkt der Erstellung dieses Buchmanuskriptes, an dem die erste offizielle XQuery-Sprachversion noch nicht einmal verabschiedet ist, in keiner Weise belegbar und hätten daher eine ausschließlich marketing-lastige Bedeutung. Ich hoffe aber, dass Sie durch das Studium dieses Buches und mögliche erste eigene Experimente mit der neuen Sprache XQuery neugierig geworden sind und die weitere Entwicklung von XQuery mit Interesse verfolgen werden. Denn aufgrund der beschriebenen Perspektiven und Einsatzmöglichkeiten kann XQuery durchaus zu dem werden, was derzeit schon viele der neuen Sprache voraussagen, nämlich zu „XQuery – dem SQL des 21.Jahrhunderts“. 20
Eine solcher Vergleich wäre natürlich auch unfair, denn dabei würde man einen über viele Jahre gewachsenen Standard (SQL) mit einem noch nicht einmal endgültig verabschiedeten Standard (XQuery) vergleichen.
158
Literatur
Literatur [Bru04] Michael Brundage, XQuery – The XML Query Language, Addison Wesley 2004 [BUMB] BumbleBee: http://xquery.com/bumblebee/ [FIT03] Michael Fitzgerald: Learning XSLT, O’Reilly 2003 [GAL] Galax-Implementierung: http://www.galaxquery.org/ [IPS] IPSI-XQ-Implementierung: http://www.ipsi.fraunhofer.de/oasys/projects/ipsi-xq/overview_d.html [Kat03] Howard Katz (Hrsg.) u.a.: XQuery from the Experts – A Guide to the W3C XML Query Language, Addison-Wesley 2003 [KAWA] Kawa Framework: http://www.gnu.org/software/kawa/ [QEXO] Qexo – The GNU Kawa implementation of XQuery http://www.gnu.org/software/qexo [QIZ] qizx/open-Implementierung: http://www.xfra.net/qizxopen/ [SIM02] John E. Simpson: XPath and XPointer, O’Reilly 2002 [SAX] Saxon-Implementierung: http://www.saxonica.com/ [TAM] Tamino: http://www2.softwareag.com/de/products/tamino/default.asp [VDF02] Eric van der Vlist: XML Schema, O’Reilly 2002 [VLDB03] Proceedings of the 29th International Conference on Very Large DataBases, Morgan Kaufmann Publishers 2003 [XIME04] Proceedings of the First International Workshop on XQuery Implementation, Experience and Perspectives , ACM SIGMOD 2004 [XQDM] XQuery 1.0 and XPath 2.0 Data Model W3C Working Draft 12.Nov 2003, http://www.w3.org/TR/xpath-datamodel/ [XQF] XQuery 1.0 and XPath 2.0 Functions and Operators W3C Working Draft 12.Nov 2003, http://www.w3.org/TR/xpath-functions/
159
Literatur
[XQJ] XQuery API for Java (XQJ) 1.0 Specification Version 0.2.1 (Early Draft Review) W3C Working Draft 10.May 2004, http://jcp.org/aboutJava/communityprocess/edr/jsr225/index.html [XQR] XQuery Requirements W3C Working Draft 12.Nov 2003, http://www.w3.org/TR/xquery-requirements/ [XSD] XML Schema Part 2: Datatypes W3C Recommendation 02 May 2001 http://www.w3.org/TR/xmlschema-2/ [XSym03] Database and XML Technologies – First International XML Database Symposium, XSym 2003, Springer-Verlag LNCS 2824
160
Autor
Autor Rudolf Jansen
Rudolf Jansen ist freiberuflicher SoftwareEntwickler und Fachautor aus Aachen. Er hat mehrjährige praktische Erfahrungen in den Bereichen Oracle, Java, C++ und XML. Er ist Autor der im Software & Support Verlag erschienenen Bücher „Oracle, Java, XML: Integration in Oracle 9i; Architekturansätze für die Praxis“ und „Java Persistenz-Strategien“ und schreibt Artikel für Fachzeitschriften, u.a. für das Java Magazin und das XML Magazin. Außerdem ist er als Referent auf Entwicklerkonferenzen tätig und bietet Schulungen zu den genannten Themen an. Sie erreichen ihn unter der E-Mail-Adresse
[email protected].
161
Index
Index A Abstract Syntax Tree .......... 132 Achse..................................... 22 allgemeine Vergleiche .......... 72 and......................................... 69 arithmetische Operatoren...... 71 as ........................................... 98 ascending............................... 59 at ........................................... 51 Atomization......................... 102 attribute()............................... 90 avg......................................... 71 B base-uri() ............................... 90 benutzerdefinierte Fehlermeldung ................ 126 benutzerdefinierte Funktionen ...................... 113 Boolean ................................. 82 BumbleBee.......................... 144 byte........................................ 87 C cast as .................................... 99 castable as ............................. 99 Casting .................................. 59 ceiling.................................... 71 Character Information Items. 31 codepoints ........................... 112 code-points-to-string........... 110
collation ...............................113 collection()...........................104 comment()..............................90 compare ...............................110 concat...................................110 contains................................110 count()..................................105 D data()..............................90, 102 date ........................................91 dateTime ................................91 Datums-Datentypen...............91 dayTimeDuration...................92 decimal ..................................87 Default-Namespace ...............98 descending .............................59 distinct-values................49, 107 div ..........................................71 doc().....................................104 document-node()....................90 Document-Type-Definition ...34 Dokumentenreihenfolge .60, 84, 107 double ....................................87 down-casting........................100 DTD .......................................34 duration..................................92 dynamischer Kontext...........134
163
Index
E
I
EBV ...................................... 82 Effektive Boolean Value....... 82 element() ............................... 90 empty .................................. 107 empty greatest....................... 60 empty least ............................ 60 ends-with............................. 110 ENTITY ................................ 89 eq .......................................... 78 error() .................................. 126 escape-uri ............................ 110 every...................................... 55 exists ................................... 107 expanded-QName ................. 96 external ............................... 119 externe Funktionen ............. 119
ID...........................................89 idiv.........................................71 IDREF ...................................89 if-then-else.............................70 import ............................96, 121 index-of ...............................107 Inputfunktionen ...................103 insert-before ........................107 instance of ...........................100 int...........................................87 IPSI........................79, 132, 136
F
K
Fehlerbehandlung ............... 125 float ....................................... 87 floor....................................... 71 FLWOR ................................ 44 for.......................................... 50
Kawa....................................137 Knotentest..............................23 Konkatenation .......................67
G Galax................................... 141 ge .......................................... 78 get-hours-from-dateTime() ... 95 get-minutes-from-dateTime.. 95 Gruppierung........................ 108 gt .......................................... 78
164
J Java......................119, 127, 145 JDBC ...................................147 Joins.....................................122
L language ................................89 le ...........................................78 left outer join .......................125 let ...........................................51 lexikografische Sortierung ....58 library module .....................120 local-name() ..........................90 Logische Operatoren .............69 Lokalisierungsschritt .............22 long........................................87
Index
Lorel...................................... 16 lower-case ........................... 110 lt ........................................... 78 M main module........................ 120 matches ............................... 110 max........................................ 71 min ........................................ 71 mod ....................................... 71 Module ................................ 119 N Name ..................................... 89 Namensraum ....................... 121 namespace() .......................... 90 namespace-uri()..................... 90 NaN ....................................... 83 NCName ............................... 89 ne ........................................... 78 negativeInteger...................... 87 NMTOKEN........................... 89 node-kind()............................ 90 node-name() .......................... 90 nonNegativeInteger............... 87 nonPositiveInteger ................ 87 normalizedString................... 89 not ......................................... 69 numerische Sortierung .......... 59 O occurrence indicator.............. 86 or ........................................... 69 Oracle.................................. 136 order by ................................. 57
P Parsing .................................132 Prädikat..................................23 processing-instruction().........90 Prolog ..................................119 Q Qexo ....................137, 146, 155 Qizx .....................................142 QName...................................96 Query-Optimierung ...............10 Quilt .......................................16 R Reihenfolge-Operatoren ........83 rekursive Funktionen ...........118 replace..................................111 return......................................61 round......................................72 round-half-to-even.................72 Rückgabewert ........................61 S Saxon ...........................135, 143 Sequenz..................................85 Funktionen.......................105 Servlets ................................155 short .......................................87 some.......................................54 SQL........................................16 SQL/XML......................16, 157 SQLJ ....................................148 starts-with ............................111 statischer Kontext ................132 string ......................................89
165
Index
string()............................. 66, 90 string-join............................ 111 string-length........................ 111 String-Operationen ............. 109 string-to-codepoints ............ 111 string-value ........................... 91 Stylesheet .............................. 31 substring.............................. 111 sum........................................ 72 Systemfehlermeldung ......... 126 T Tamino ................................ 143 template................................. 31 text()...................................... 90 Textknoten ............................ 63 time ....................................... 92 token ..................................... 89 tokenize............................... 112 translate............................... 112 treat as ................................. 100 Tupel ..................................... 50 Typ-Casting .......................... 59 typed-value ..................... 58, 90 typeswitch ........................... 101 Typkonvertierung ................. 88 Typkonzept ........................... 85 Typoperatoren....................... 98 Typumwandlungen ............. 102 U unordered ............................ 107 unsignedByte ........................ 87 unsignedInt ........................... 87 unsignedLong ....................... 87
166
unsignedShort........................87 untypedAtomic ......................96 update ..................................156 upper-case............................112 V Vergleichs-Operatoren ..........72 W W3C.......................................16 Wertevergleiche ..............72, 78 where .....................................53 X XMLAgg ...............................16 XML-Dokumente datenorientierte..................19 dokumentenorientierte.......19 hybride...............................20 XMLElement.........................16 XMLForest ............................16 XML-GL ...............................16 XML-QL ...............................16 XMLQuery ............................17 XML-Schema ........36, 117, 122 XPath .....................................22 Achse .................................22 Datentypen ........................29 Knotentest..........................23 Lokalisierungsschritt .........22 Prädikat..............................23 XQJ......................................147 XQL.......................................16 XQuery-Core-Language......132 XQuery-Engine .....................14
Index
XSL ....................................... 16 XSLT..................................... 30 Stylesheet .......................... 31
Y yearMonthDuration ...............92 Z Zeit-Datentypen.....................91
167