Oracle XMLType und XPath

XML ist heutzutage ein Standardformat für viele Zwecke im Internet und in der Datenverarbeitung. Um mit XML zu arbeiten, unterstützen Oracle Datenbanken den Datentyp XMLType. Dieser kann sowohl als einfache Variable als auch in einer Tabelle zur Definition einer Spalte verwendet werden. Somit lassen sich komplette XML Dokumente in der Datenbank ablegen und deren Inhalt sogar mit SQL abfragen.

Ein Hilfsmittel, um Daten aus einem XML Dokument abzufragen, ist XPath. Mit Hilfe von XPath ist es möglich durch den XML-Baum zu navigieren und bestimmte Knoten anzusprechen, auszulesen oder zu manipulieren.

Während meiner Arbeit hatte ich letztens mit diesem XML Datentyp in Form einer Variablen zu tun. Um bestimmte Knotenwerte des XML-Baums auszulesen, verwendete ich XPath. Hier nun eine kurze Beschreibung wie das ganze Funktioniert.

Zuallererst braucht man natürlich ein XML Dokument. Für Testzwecke kann das folgende verwendet werden:

<?xml version="1.0" encoding="ISO-8859-1"?>
<cdsammlung>
 <cd>
 <titel>Nevermind</titel>
 <kuenstler>Nirvana</kuenstler>
 <jahr>1991</jahr>
 <preis>15,98</preis>
 </cd>
</cdsammlung>

Zunächst muss dieses XML Dokument natürlich als Variable deklariert werden. Dazu wird der Datentyp sys.Xmltype verwendet:

declare
  xmlDoc sys.Xmltype;
  helper varchar2(64);
begin
  xmlDoc := sys.Xmltype('<?xml version="1.0" encoding="ISO-8859-1"?>
                         <cdsammlung>
                           <cd>
                             <titel>Nevermind</titel>
                             <kuenstler>Nirvana</kuenstler>
                             <jahr>1991</jahr>
                             <preis>15,98</preis>
                          </cd>
                        </cdsammlung>');
end;

Um nun zum Beispiel den Titel der ersten CD aus unserem XML Dokument auszugeben, müssen wir zunächst mit XPath zu dem entsprechenden Knoten navigieren. Um einzelne Knoten aus dem Dokument zu extrahieren, enthält Xmltype die Memberfunktion extract(). Mit ihrer Hilfe kann man den entsprechenden Knoten per XPath ansprechen:

SYS.XMLTYPE.extract(xmlDoc, '/cdsammlung/cd/titel')

Den Rückgabewert dieses Funktionsaufruf kann man mit dbms_output ausgeben. Dazu sollte man den Wert jedoch erst mit sys.Xmltype.getStringVal() umwandeln:

helper := SYS.XMLTYPE.getStringVal(SYS.XMLTYPE.extract(xmlDoc, '/cdsammlung/cd/titel'));
dbms_output.put_line('Titel Knoten: ' || helper);

Die Ausgabe sollte wie folgt aussehen:

Titel Knoten: <titel>Nevermind</titel>

Da der oben verwendete XPath Ausdruck den gesamten Knoten anspricht, wird auch der gesamte Knoten zurück- und ausgegeben. Das schließt natürlich auch die XML Tags mit ein. Um nur den Wert des Knotens auszugeben, muss man dies explizit im XPath Ausdruck angeben:

helper := SYS.XMLTYPE.getStringVal(SYS.XMLTYPE.extract(xmlDoc, '/cdsammlung/cd/titel/text()'));
dbms_output.put_line('Titel Wert: ' || helper);

Mit diesem XPath Ausdruck sollte nun nur noch der Wert des Knotens ausgegeben werden:

Titel Wert: Nevermind

Der gesamte PL/SQL Block um das beschriebene Beispiel auszuführen sieht wie folgt aus:

declare
  xmlDoc sys.Xmltype;
  helper varchar2(64);
begin
  xmlDoc := sys.Xmltype('<?xml version="1.0" encoding="ISO-8859-1"?>
                         <cdsammlung>
                           <cd>
                             <titel>Nevermind</titel>
                             <kuenstler>Nirvana</kuenstler>
                             <jahr>1991</jahr>
                             <preis>15,98</preis>
                          </cd>
                       </cdsammlung>');

  helper := SYS.XMLTYPE.getStringVal(SYS.XMLTYPE.extract(xmlDoc, '/cdsammlung/cd/titel'));
  dbms_output.put_line('Titel Knoten: ' || helper);

  helper := SYS.XMLTYPE.getStringVal(SYS.XMLTYPE.extract(xmlDoc, '/cdsammlung/cd/titel/text()'));
  dbms_output.put_line('Titel Wert: ' || helper);
end;

Ein recht gutes Tutorial für den Start mit XPath kann man auf der Seite der W3C Schools finden. Damit sollte ausgiebigen Spielereien mit XML Dokumenten in Oracle nichts mehr im Wege stehen 😉

Leave a Reply