In diesem Kapitel lernen Sie, welche Publikationsfunktionen es in SQL/XML gibt und wie diese Funktionen eingesetzt werden, um komplexe XML Dokumente zu generieren welchen Nutzen die architekturgetriebene Entwicklung von XML Dokumenten bringt welche Bedeutung die strukturierte und ästhetische Programmniederschrift zur Beherrschung der Komplexität leistet. Mit Ihrem erworbenen Wissen können Sie sodann beliebig komplexe XML Dokumente aus relationalen Daten erzeugen. 4. XML-Sprachkonstrukte ein kurzer Überblick An einem kleinen Beispiel eines XML Dokumentes werden die Sprachkonstrukte von XML gezeigt, siehe XML Dokument 3. Für die Generierung der Sprachkonstrukte werden die hierfür bestimmten SQL/XML Publikationsfunktionen, die in Tabelle 2 kurz aufgeführt sind, sodann detailliert vorgestellt und an zahlreichen Beispielen demonstriert. Ein XML Dokument muss wohlgeformt sein. Hierzu muss es folgende Bedingungen erfüllen. Jeder Datenwert eines XML Elementes muss von einem Start und Ende tag umschlossen sein. Ein XML Dokument kann nur ein einziges Wurzelelement haben. Jedes XML Element kann nur ein ihm unmittelbar hierarchisch übergeordnetes XML Element haben. Ein XML Dokument besitzt somit eine Baumstruktur. XML Elemente dürfen sich nicht überlappen, indem das Ende tag eines übergeordneten Elementes vor dem Ende tag eines untergeordneten XML Elementes steht. Einem Elementattribut muss ein Wert zugeordnet werden. Dieser muss in Hochkommata (einzelne oder Gänsefüße) eingeschlossen sein. Folgende Sonderzeichen dürfen nicht in den Namen und in den Texten verwendet werden, sondern müssen durch so genannte Entities ersetzt werden: Spitzklammer auf ʺ<ʺ Entity: < Spitzklammer zu ʺ>ʺ Entity: > 35
Und Zeichen ʺ&ʺ Entity: & Gänsefuß ʺ Entity: " Apostroph ʹ Entity: ' Wenn ein XML Dokument dann noch von einem validierenden Parser unter Beachtung der Vorgaben eines XML Schemas für korrekt erachtet wurde, so wird es als valide bezeichnet. Wohlgeformtheit und Validität sind somit wesentliche Qualitätskriterien für ein XML Dokument. Im folgenden einfachen XML Dokument 3 sind die beispielhaften XML Sprachkonstrukte dargestellt. Die zu ihrer Generierung in SQL/XML verfügbaren eingebauten Funktionen werden anschließend kurz angegeben. In den sodann folgenden Kapiteln werden die eingebauten SQL/XML Funktionen ausführlich in ihrem Zusammenwirken dargestellt. <?xml version=".0" encoding="utf-8"?> () <?Verarbeitungshinweis irgend etwas?> (2) <mo:elementname (3) xmlns:mo="http://alfred-moos.de" (4) mo:attributname = "Attributwert"> (5) <!-- Kommentar --> (6) Elementwert (7) Das ist ein Text (8) </mo:elementname> (9) XML Dokument 3: Beispiel für XML Sprachkonstrukte Die folgende Tabelle 5 gibt einen Hinweis auf die Namen der eingebauten SQL/XML Funktionen, welche die XML Konstrukte im obigen XML Dokument 3 erzeugten. Obige Zeile XML Konstrukt Name der eingebauten SQL/XML Funktion () Funktion: XMLSERIALIZE (2) Funktion: XMLPI (3), <mo:elementname (7) und </mo:elementname (9) Funktion: XMLELEMENT (4) xmlns:mo = ʺhttp://Alfred Moos.deʺ Funktion: XMLNAMESPACES (5) mo:attributname = ʺAttributwertʺ Funktion: XMLATTRIBUTES 36
(6) <! Kommentar > Funktion: XMLCOMMENT (8) Das ist ein Text Funktion: XMLTEXT 4.2 XMLDOCUMENT erzeugt ein XML Dokument Tabelle 5: XML Konstrukte und die sie generierenden SQL/XML Funktionen In den folgenden Kapiteln werden die SQL/XML Funktionen detailliert erklärt. 4.2 XMLDOCUMENT erzeugt ein XML-Dokument Die eingebaute SQL/XML Funktion XMLDOCUMENT() erzeugt ein XML Dokument in seiner intern codierten Form und somit einen Wert des Typs XML. Er wird auch als Dokumentknoten bezeichnet. Er ist der interne Wurzelknoten einer Baumstruktur, die aus vielen Knoten unterschiedlicher Typen bestehen kann. Ein Dokumentenknoten umschließt die interne Repräsentation eines XML Dokumentes. Er ist ein virtueller Datenmodellknoten des XQuery Data Model (XDM). Virtuell deshalb, weil er sich nicht in einem XML Konstrukt niederschlägt, wenn das Dokument in seine externe zeichenartige Repräsentation umgewandelt wird. Einem Dokumentknoten können null bis viele Nachfolgerknoten untergeordnet sein. Folgende Arten an Nachfolgerknoten sind möglich: Elementknoten Textknoten Verarbeitungshinweisknoten (processing instruction) Kommentarknoten Das folgende Klassendiagramm zeigt auf der Typebene den Zusammenhang zwischen einem Dokumentknoten und den von ihm abhängigen Knoten. «Document» Dokumentknoten Elementknoten «Textk» Textknoten «Processing instruction» Verarbeitungshinweisknoten «Comment» Kommentarknoten Abbildung 7: Dokumentknoten und seine abhängigen Knotenarten 37
Ein Dokumentknoten wird mit der eingebauten Funktion XMLDOCUMENT() erzeugt. Die Syntax der SQL/XML Funktion in der Backus Naur Notationsform zeigt die folgende Syntaxbeschreibung. XMLDOCUMENT( XML-Ausdruck ) Syntax 2: Syntax von XMLDOCUMENT() Ein XML Dokument in seiner externen Textform muss genau ein XML Element als Dokumentwurzel haben. Der hierzu korrespondierende interne XML Elementknoten wird durch die eingebaute SQL/XML Funktion XMLELEMENT() erzeugt. Ihr Aufruf muss somit Bestandteil des obigen XML Ausdrucks sein. Im folgenden Kapitel wird das Zusammenspiel beider Funktionen lauffähig demonstriert. 4.3 XMLELEMENT erzeugt ein XML-Element Ein XML Element besteht in seiner textartigen externen Form im einfachsten Fall aus seinen beiden Tags, dem Start und dem Ende Tag, und seinem Wert. Bei einem so genannten leeren XML Element gibt es den Wert nicht. Ein XML Element kann durch viele Attribute näher beschrieben werden. Auf XML Element Attribute gehen wir im Kapitel XMLATTRIBUTES() näher ein. Die eingebaute SQL/XML Funktion XMLELEMENT() erzeugt einen XML Elementknoten in interner Codierung. Da ein XML Dokument überwiegend aus XML Elementen besteht, bildet die Anwendung von XMLELEMENT() auch einen erheblichen Teil der SQL Publikationsprogramme. Ein Elementknoten (Stereotyp <<Element>>) repräsentiert intern ein XML Element. Die Nachfolgerknoten können von folgenden Arten sein: Elementknoten Textknoten Verarbeitungshinweisknoten (processing instruction) Kommentarknoten. Als Vorgängerknoten kommen in Betracht: ein Elementknoten oder ein Dokumentknoten. Dokument bzw. Attributknoten können keine Nachfolgerknoten von einem Elementknoten sein. Jedoch kann einem Elementknoten ein oder mehrere Attributknoten zugeordnet werden. Ein Attributknoten ist seinem Elementknoten nur zugeordnet aber nicht hierarchisch untergeordnet. Im Rahmen der Zuordnung bezeichnet man den Elementknoten eines Attributknotens dennoch als dessen Parent Knoten. 38
4.3 XMLELEMENT erzeugt ein XML Element Parent-Child- Beziehung Elementknoten Elementknoten «Textk» Textknoten «Processing instruction» Verarbeitungshinweisknoten «Comment» Kommentarknoten nur Parent- Beziehung «Attributek» Attributknoten Abbildung 8: Elementknoten und seine abhängigen Knotenarten Ein Elementknoten wird mit der eingebauten Funktion XMLELEMENT() erzeugt. Ihre zunächst vereinfachte Syntax in der Backus Naur Notationsform zeigt das folgende Syntaxdiagramm. XMLELEMENT( NAME Elementname, Elementinhaltsausdruck [, Elementinhaltsausdruck]... [OPTION {NULL ON NULL EMPTY ON NULL}] Syntax 3: Vereinfachte Syntax von XMLELEMENT() Den Elementnamen muss man in doppelten Hochkommata (Gänsefüßchen) schreiben. Der Elementinhaltsausdruck ist ein beliebiger SQL Ausdruck, dessen Ergebnis ein skalarer Wert sein muss. Mit den Optionen OPTION NULL ON NULL oder OPTION EMPTY ON NULL kann gesteuert werden, was zu generieren ist, wenn der auszugebende Elementinhaltsausdruck der Wert NULL ist. Wird keine Option angegeben, wird die unterstrichene Option NULL ON NULL als Default angenommen. Beispiel XMLELEMENT( NAME ʺAnredeʺ, ʹFrauʹ ) 39
4.4 XMLSERIALIZE erzeugt Zeichenform Die interne Repräsentation eines XML Dokumentes muss in ihre externe Zeichenform konvertiert werden, damit man das XML Dokument in gewohnter Weise lesen kann. Die Umwandlung eines internen XML Dokumentes in seine externe Form bezeichnet man auch als serialisieren. Durch den Einsatz der SQL/XML Funktion XMLSERIALIZE() wird die Serialisierung durchgeführt. Das folgende Syntaxdiagramm zeigt vereinfacht den Aufbau der Funktion. XMLSERIALIZE( XML-Ausdruck AS { CLOB [(Ganzzahl)] CHAR [(Ganzzahl)] VARCHAR (Ganzzahl) BLOB [(Ganzzahl)] } Version '.0' [INCLUDING XMLDECLARATION] o [EXCLUDING XMLDECLARATION] Syntax 4: Vereinfachte Syntax der Funktion XMLSERIALIZE() Das Zusammenwirken der bis jetzt dargestellten eingebauten SQL/XML Funktionen XMLSERIALIZE() XMLDOCUMENT() XMLELEMENT() wird im nächsten Schritt an einem einführenden und einfachen Beispiel gezeigt. Hierbei soll das folgende XML Dokument erzeugt werden. <Anrede>Frau</Anrede> Mit der Anwendung der SQL Klausel VALUES wird eine minimale Ausführungsumgebung für DB2 SQL geschaffen. VALUES (XMLSERIALIZE( () XMLDOCUMENT( (2) XMLELEMENT( NAME "Anrede", 'Frau' (3) ) (4) ) (5) AS CLOB (6) ) (7) ) (8) ; (9) Programm 2: Einführendes Beispiel in die Publikationsfunktionen von SQL/XML Ergebnis <Anrede>Frau</Anrede> 40
4.4 XMLSERIALIZE erzeugt Zeichenform Die Funktion XMLSERIALIZE() in der Zeile () erhält den XML Wert, der von der Funktion XMLDOCUMENT() erzeugt wurde. Diese erhält als Wert den Elementknoten, welcher durch die Funktion XMLELEMENT() ausgeprägt wurde. Die Funktion XMLSERIALIZE() konvertiert die interne Repräsentation des XML Dokumentes in eine zeichenartige externe Repräsentation im Datentyp CLOB, siehe Zeile (6). SQL/XML Programme, welche die Publikationsfunktionen enthalten, zeichnen sich durch eine verhältnismäßig tiefe Ineinanderschachtelung dieser Funktionen aus. Dies führt dazu, dass auch der versierte SQL Fachmann recht schnell die Übersicht verliert und nicht mehr übersieht, wohin die schließende Klammer eines Funktionsaufrufes zu platzieren ist. Diese Art der globalen Komplexität kann nur durch eine systematische Platzierung der schließenden Funktionsklammern reduziert werden. Wir empfehlen eindrücklich, unserem Vorschlag für die Programmniederschrift zu folgen. Damit das generierte XML Dokument von einem validierenden XML Parser als ein Dokument erkannt wird, in dem die XML Sprache der Version.0 angewandt ist, ist noch der Hinweis VERSION ʹ.0ʹ erforderlich. Mit der weiteren optionalen Klausel INCLUDING XMLDECLARATION wird die Funktion XMLSERIALIZE() beauftragt, in die erste Zeile des XML Dokumentes den Verarbeitungshinweis <?xml version=ʺ.0ʺ encoding=ʺutf 8ʺ?> hineinzugenerieren. In der Zeile (6) des folgenden Programms ist die Anwendung dieser weiteren Klauseln der Funktion XMLSERIALIZE() dargestellt. VALUES (XMLSERIALIZE( () XMLDOCUMENT( (2) XMLELEMENT( NAME "Anrede", 'Frau' (3) ) (4) ) (5) AS CLOB VERSION '.0' INCLUDING XMLDECLARATION (6) ) (7) ) (8) ; (9) Programm 3: XMLSERIALIZE() mit den Klauseln VERSION ʹ.0ʹ und INCLUDING XMLDECLARATION Ergebnis <? xml version=ʺ.0ʺ encoding=ʺutf 8ʺ?> <Anrede>Frau</Anrede> In der Zeile (3) von Programm 3 ist als Elementinhaltsausdruck das Zeichenliteral ʹFrauʹ angegeben. Diese einführende Vereinfachung wird jetzt aufgehoben. Als neuer Elementinhaltsausdruck wird nun der Spaltenname Anrede der Tabelle Kunde verwendet, siehe Programm 4. In der WHERE Klausel des SELECT 4
Befehls wird das Prädikat Kunde_Nr = ʹK00ʹ angegeben, damit nur die Zeile des Kunden Hugo Müller gelesen wird. Im Zuge der architekturgetriebenen Softwareentwicklung, die wir im Fortgang weiterhin praktizieren wollen, entwickeln wir zunächst in UML das Modell des zu generierenden XML Dokumentes auf der Typ und auf der Ausprägungsebene. Anschließend verwenden wir den Modellentwurf (design) des zu generierenden XML Dokumentes als abstrakte Vorlage für das zu schreibende SQL/XML Programm. Diese Vorgehensweise ist hilfreich, um die Übersicht bei der Implementierung nicht zu verlieren. Relationales Datenbankmodell XML Schemamodell Typebene Exemplarebene «table» Kunde Anrede «instantiate» K00:Anrede Kunde_Nr : CHAR(4) Anrede : CHAR(4) Vorname : CHAR(5) Zuname : CHAR(5) Strasse : CHAR(5) PLZ : CHAR(5) Ort : CHAR(5) Abbildung 9: Einfaches XML Schemamodell in UML Die Informationen aus dem relationalen Datenbankmodell und dem XML Schemamodell werden nun im folgenden SQL Programm verfeinert und mit dem Sprachvorrat von SQL/XML formuliert. Dieses generiert das gewünschte XML Dokument in seiner externen Form. SELECT XMLSERIALIZE( () XMLDOCUMENT( (2) XMLELEMENT( NAME "Anrede", K.Anrede (3) ) (4) ) (5) AS CLOB VERSION '.0' (6) INCLUDING XMLDECLARATION ) (7) FROM Kunde AS K (8) WHERE Kunde_Nr = 'K00' (9) ; (0) Programm 4: Elementinhaltswert ist nun die Spalte Anrede der Tabelle Kunde 42
4.4 XMLSERIALIZE erzeugt Zeichenform Ergebnis <?xml version=".0" encoding="utf-8"?> <Anrede>Herr</Anrede> Im nun folgenden XML Dokument sollen alle Daten des Kunden Hugo Müller mit der Kundennummer K00 ausgegeben werden. Die Begriffsbezeichner, d. h. die Namen der XML Elemente, sollen dieselben sein, die auch für die Benennung der Attribute des Entitätstyps Kunde und hiervon abgeleitet für die Attributnamen des Relationstyps Kunde und auch hiervon abgeleitet für die Implementierung der Tabelle Kunde verwendet wurden. Die Konsistenz bei der Verwendung des Vokabulars ist wichtig. Sie gewährleistet das Verständnis des Systemzusammenhangs über die verschiedenen Stufen der Softwareentwicklung. Im folgenden XML Schemamodell wird auch der Dokumentknoten in die Architektur mit aufgenommen. Wie bereits erwähnt, tritt er im publizierten externen XML Dokument nicht in Erscheinung. «table» Kunde Kunde_Nr : CHAR(4) Anrede : CHAR(4) Vorname : CHAR(5) Zuname : CHAR(5) Strasse : CHAR(5) PLZ : CHAR(5) Ort : CHAR(5) Relationales Datenbankmodell links XML-Schema-Modell unten «Document» Dokument «Processing instruction» XML Deklaration Kunde Kunde_Nr Anrede Vorname Zuname Strasse PLZ Ort Abbildung 20: XML Schema Modell Kunde 43
Das folgende SQL/XML Programm setzt das XML Schema Modell um und erzeugt das gewünschte XML Dokument. Der Elementinhaltsausdruck der äußeren Funktion XMLELEMENT() in Zeile (3), der das Wurzelelement Kunde erzeugt, besteht aus einer Folge von XMLELEMENT() Funktionsaufrufen. Diese stehen in Zeile (4) bis (7). SELECT XMLSERIALIZE( () XMLDOCUMENT( (2) XMLELEMENT( NAME "Kunde", (3) XMLELEMENT( NAME "Kunde_Nr", K.Kunde_Nr (4) ), (5) XMLELEMENT( NAME "Anrede", K.Anrede (6) ), (7) XMLELEMENT( NAME "Vorname", K.Vorname (8) ), (9) XMLELEMENT( NAME "Zuname", K.Zuname (0) ), () XMLELEMENT( NAME "Strasse", K.Strasse (2) ), (3) XMLELEMENT( NAME "PLZ", K.PLZ (4) ), (5) XMLELEMENT( NAME "Ort", K.Ort (6) ) (7) ) (8) ) (9) AS CLOB VERSION '.0' (20) INCLUDING XMLDECLARATION (2) ) (22) FROM Kunde AS K (23) WHERE Kunde_Nr = 'K00' (24) ; (25) Programm 5 : Programm Kunde mit der Funktion XMLELEMENT Zur aufbereiteten Ausgabe des von DB2 erzeugten und serialisierten Datenstromes kann der Internet Explorer der Firma Microsoft verwendet werden. Hierzu kopiert man die Ausgabedaten in eine Textdatei mit dem Suffix XML und öffnet diese Datei mit dem Internet Explorer. Ergebnis <?xml version=".0" encoding="utf-8"?> - <Kunde> <Kunde_Nr>K00</Kunde_Nr> <Anrede>Herr</Anrede> <Vorname>Hugo</Vorname> <Zuname>Mueller</Zuname> <Strasse>Gartenstr. 4a</Strasse> <PLZ>6923</PLZ> <Ort>Heidelberg</Ort> </Kunde> 44