XMLType Christian Senger/Andreas Schmidt XMLType 1/32
XMLType von Oracle vordefinierter Typ zur Speicherung von nativen XML-Dokumenten unterstützt verschiedene Speichermodelle für XML structured storage (speicherung relational - nur mit XML-Schema möglich) binary xml storage (mit/ohne XML-Schema) unstructured storage (als CLOB) hybrid storage (mix aus obigen drei Modellen) Funktionen zur Unterstützung der SELECT-Anfragen auf XMLType Instanzen Funktionen zur Unterstützung der UPDATE-Operationen von XML-Dokumenten XML-Schema und XQuery Unterstützung Christian Senger/Andreas Schmidt XMLType 2/32
XMLType Funktionen zur Unterstützung der SQL-Anfragen auf XMLType Instanzen: extractvalue(xmltype, XPath) extract(xmltype, XPath) existsnode(xmltype, XPath) xmlsequence(xmltype) table(xmlsequencetype) Beispiel... -> Christian Senger/Andreas Schmidt XMLType 3/32
Beispiel create table xml_test ( id number primary key, document xmltype not null ); insert into xml_test (id, document) values(1,xmltype('<land name="deutschland"> <city>karlsruhe</city> <city>stuttgart</city> </land>')); insert into xml_test (id, document) values(2,xmltype('<land name="frankreich"> <city>strassburg</city> <city>marseille</city> </land>')); select * from xml_test; ID DOCUMENT ----- -------------------- 1 <land name="deutschland"> <city>karlsruhe</city> <city>stuttgart</city> </land> 2 <land name="frankreich"> <city>strassburg</city> <city>marseille</city> </land> 2 Zeilen ausgewõhlt. Christian Senger/Andreas Schmidt XMLType 4/32
extractvalue(...), existsnode(...) extractvalue(...): liefert skalaren Wert (Zeichenkette, Number) eines Knotens zurück select extractvalue(document,'/land/@name') from xml_test; EXTRACTVALUE(DOCUMENT,'/LAND/@NAME') ---------------------------------------- Deutschland Frankreich 2 Zeilen ausgewõhlt. existsnode(...): liefert 1 zurück, wennn der XPath etwas zurückliefert, sonst 0 select extractvalue(document,'/land/@name') from xml_test where existsnode(document,'//city[text()="stuttgart"]')=1; EXTRACTVALUE(DOCUMENT,'/LAND/@NAME') ---------------------------------------------- Deutschland 1 Zeile wurde ausgewõhlt. Christian Senger/Andreas Schmidt XMLType 5/32
extract(...) select extractvalue(document,'//city') from xml_test where existsnode(document,'/land[@name="frankreich"]')=1; FEHLER in Zeile 2: ORA-19025: EXTRACTVALUE gibt Wert von nur einem Knoten zur³ck extract(...): liefert XMLType Instanz zurück select extract(document,'//city') from xml_test where existsnode(document,'/land[@name="frankreich"]')=1; EXTRACT(DOCUMENT,'//CITY') ------------------------------------------------- xmltype(<city>strassburg</city><city>marseille</city>) 1 Zeile wurde ausgewõhlt. Christian Senger/Andreas Schmidt XMLType 6/32
xmlsequence(...) Frage: wie kann ich auf die einzelnen Städte zugreifen? aufspalten des XML-Fragments auf oberster Elementebene (Ergebnis: Liste) select xmlsequence(extract(document,'//city')) from xml_test where existsnode(document,'/land[@name="frankreich"]')=1; XMLSEQUENCE(EXTRACT(DOCUMENT,'//CITY')) -------------------------------------------------- XMLSEQUENCETYPE( XMLTYPE(<city>Strassburg</city>), XMLTYPE(<city>Marseille</city>) ) 1 Zeile wurde ausgewõhlt. Christian Senger/Andreas Schmidt XMLType 7/32
table(...) - Operator wie komm ich an die einzelnen Felder der Liste ran? table(...) Operator wandelt Liste in Tabelle um select extractvalue(column_value,'/city/text()') from table ( select xmlsequence(extract(document,'//city')) from xml_test where existsnode(document,'/land[@name="frankreich"]')=1 ); EXTRACTVALUE(COLUMN_VALUE,'/CITY/TEXT()') ---------------------------------------------------------- Strassburg Marseille 2 Zeilen ausgewõhlt. Umwandlung einer Liste in eine Tabelle Christian Senger/Andreas Schmidt XMLType 8/32
Zusammenfassung Anfragen extract(...) liefert eine XMLType Instanz extractvalue(...) liefert den skalaren Wert eines Knotens (werden mehrere Knoten gefunden gibt es einen Fehler) mittels XMLSequence(...) kann eine XMLType Instanz auf der obersten Knotenebene aufgebrochen werden und es entsteht eine Liste aus XMLType Instanzen table(...) wandelt eine Liste in eine relationale Tabelle um, die dann weiter bearbeitet werden kann Pseudospalte column_value für den Zugriff auf die Datensätze einer mittels table(...) erzeugten Tabelle Christian Senger/Andreas Schmidt XMLType 9/32
XMLType Funktionen zur Unterstützung der Modifikationen von XML-Dokumenten updatexml: Führt ein Update eines Wertes/Elements/Attributs an der durch XPath angegebenen Stelle durch. deletexml: Löscht den/die durch den XPath angegebene(n) Elemente. insertxmlbefore: Fügt eine XMLType-Instanz vor der durch XPath spezifizierten Stelle ein. appendchildxml: Fügt eine XMLType-Instanz nach der durch den XPath spezifizierten Stelle ein. Beispiele... -> Christian Senger/Andreas Schmidt XMLType 10/32
updatexml(...) update xml_test set document = updatexml(document, '/land/@name','bundesrepublik Deutschland', '/land/city[text()="stuttgart"]/text()','stuttgart am Neckar') where existsnode(document,'/land/@name[.="deutschland"]')=1; 1 Zeile wurde aktualisiert. select document from xml_test where existsnode(document,'/land/@name[.="bundesrepublik Deutschland"]')=1; DOCUMENT -------------------------------------------------------------------- <land name="bundesrepublik Deutschland"> <city>karlsruhe</city> <city>stuttgart am Neckar</city> </land> 1 Zeile wurde ausgewõhlt. Christian Senger/Andreas Schmidt XMLType 11/32
appendchildxml(...) update xml_test set document=appendchildxml(document, '/land',xmltype('<city>dresden</city>')) where existsnode(document,'/land/@name[.="bundesrepublik Deutschland"]')=1; 1 Zeile wurde aktualisiert. select document from xml_test where existsnode(document,'/land/@name[.="bundesrepublik Deutschland"]')=1; DOCUMENT ------------------------------------------------- <land name="bundesrepublik Deutschland"> <city>karlsruhe</city> <city>stuttgart am Neckar</city> <city>dresden</city> </land> 1 Zeile wurde ausgewõhlt. Christian Senger/Andreas Schmidt XMLType 12/32
insertchildxml(...) - Attribute update xml_test set document=insertchildxml(document, '/land/city[text()="dresden"]', '@population','518081') where existsnode(document,'/land/@name[.="bundesrepublik Deutschland"]')=1; 1 Zeile wurde aktualisiert. select document from xml_test where existsnode(document,'/land/@name[.="bundesrepublik Deutschland"]')=1; DOCUMENT --------------------------------------------------- <land name="bundesrepublik Deutschland"> <city>karlsruhe</city> <city>stuttgart am Neckar</city> <city population="518081">dresden</city> </land> 1 Zeile wurde ausgewõhlt. Christian Senger/Andreas Schmidt XMLType 13/32
insertxmlbefore(...) update xml_test set document=insertxmlbefore(document,'/land/city[last()]', xmltype('<city>metropolis</city>')) where existsnode(document,'/land/@name[.="bundesrepublik Deutschland"]')=1; 1 Zeile wurde aktualisiert. select document from xml_test where existsnode(document,'/land/@name[.="bundesrepublik Deutschland"]')=1; DOCUMENT ------------------------------------------------- <land name="bundesrepublik Deutschland"> <city>karlsruhe</city> <city>stuttgart am Neckar</city> <city>metropolis</city> <city population="518081">dresden</city> </land> 1 Zeile wurde ausgewõhlt. Christian Senger/Andreas Schmidt XMLType 14/32
deletexml(...) update xml_test set document=deletexml(document,'/land/city[text()="metropolis"]') where existsnode(document,'/land/@name[.="bundesrepublik Deutschland"]')=1; 1 Zeile wurde aktualisiert. select document from xml_test where existsnode(document,'/land/@name[.="bundesrepublik Deutschland"]')=1; DOCUMENT ---------------------------------------------------- <land name="bundesrepublik Deutschland"> <city>karlsruhe</city> <city>stuttgart am Neckar</city> <city population="518081">dresden</city> </land> 1 Zeile wurde ausgewõhlt. Christian Senger/Andreas Schmidt XMLType 15/32
deletexml(...) - Attribute update xml_test set document=deletexml(document,'/land/city[text()="dresden"]/@population') where existsnode(document,'/land/@name[.="bundesrepublik Deutschland"]')=1; 1 Zeile wurde aktualisiert. select document from xml_test where existsnode(document,'/land/@name[.="bundesrepublik Deutschland"]')=1; DOCUMENT ----------------------------------------------- <land name="bundesrepublik Deutschland"> <city>karlsruhe</city> <city>stuttgart am Neckar</city> <city>dresden</city> </land> 1 Zeile wurde ausgewõhlt. Christian Senger/Andreas Schmidt XMLType 16/32
Methode transform(...) Führt XSLT-Transformation auf XMLType Instanz aus Input: XSLT-Stylesheet Beispiel (Identity Stylesheet) set long 1000 select document.transform(xmltype('<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/> <xsl:template match="node() @*"> <xsl:copy> <xsl:apply-templates select="@* node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>')) from xml_test; Erläuterung: Das Identity-Stylesheet gibt den Input Text unverändert zurück. Durch Hinzunahme weiterer Regeln (xsl:template-elemente) können dann bestimmte Teile modifiziert werden. Christian Senger/Andreas Schmidt XMLType 17/32
DTD und Schema Unterstützung DTD Unterstützung (Überprüfung erfolgt automatisch beim Einfügen) insert into person_xml values(xmltype('<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE Person [ <!ELEMENT Person (Name, Adresse)> <!ATTLIST Person ID CDATA #REQUIRED> <!ELEMENT Adresse (Strasse, Plz, Ort)> <!ELEMENT Name (#PCDATA)> <!ELEMENT Strasse (#PCDATA)> <!ELEMENT Plz (#PCDATA)> <!ELEMENT Ort (#PCDATA)> ]> <Person ID="242"> <Name>Sebbl Seeigel</Name> <Adresse> <Strasse>An der Mole 15</Strasse> <Plz>65432</Plz> <Ort>Salzhausen</Ort> </Adresse> </Person>')); Christian Senger/Andreas Schmidt XMLType 18/32
Schema Unterstützung declare str clob; begin str := '<xs:schema xmlns:xs="http://www.w3.org/2001/xmlschema"> <xs:element name="person"> <xs:complextype> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element name="adresse"> <xs:complextype> <xs:sequence> <xs:element name="strasse" type="xs:string"/> <xs:element name="plz" type="xs:int"/> <xs:element name="ort" type="xs:string"/> </xs:sequence> </xs:complextype> </xs:element> </xs:sequence> <xs:attribute name="id" type="xs:id" use="required"/> </xs:complextype> </xs:element> </xs:schema>'; dbms_xmlschema.registerschema ('http://www.hs-karlsruhe.de/iwi/db2/simple-person.xsd', str); end; / Christian Senger/Andreas Schmidt XMLType 19/32
Schema Unterstützung Tabelle, basierend auf XML-Schema definieren create table person_schema_xml ( id number primary key, document XMLType ) XMLType column document XMLSCHEMA "http://www.hs-karlsruhe.de/iwi/db2/simple-person.xsd" ELEMENT "Person"; Datensatz einfügen: insert into person_schema_xml values(1, XMLType('<Person ID="242"> <Name>Sebbl Seeigel</Name> <Adresse> <Strasse>An der Mole 15</Strasse> <Plz>65432</Plz> <Ort>Salzhausen</Ort> </Adresse> </Person>')); Christian Senger/Andreas Schmidt XMLType 20/32
Schema Unterstützung Keine defaultmäßige Überprüfung auf Schemakonformheit beim Eintrag/Update Dokument mit Fehler der nicht erkannt wird: insert into person_schema_xml values(2, XMLType('<Person ID="243"> <Name>Johann Meier</Name> <Adresse/> </Person>')); Adresse muss laut Schema Unterelemente haben Christian Senger/Andreas Schmidt XMLType 21/32
Test für einen fehlerhaften Datensatz: Dokument mit Fehler der erkannt wird: Oracle weiss nicht was es mit Element begin Anschrift tun soll (wohin speichern?) insert into person_schema_xml values(3, XMLType('<Person ID="242"> <Name>Sebbl Seeigel</Name> <Anschrift> <Strasse>An der Mole 15</Strasse> <Plz>65432</Plz> <Ort>Salzhausen</Ort> </Anschrift> </Person>')); dbms_output.put_line('fehler: keinen Fehler im XML Dokument gefunden!!'); exception when others then dbms_output.put_line('fehler im XML Dokument erkannt'); end; / Christian Senger/Andreas Schmidt XMLType 22/32
Validierung keine automatische Validierung gegenüber Schema!! Validierung mittels zusätzlicher Methoden: member function isschemavalid(schema_url varchar2 := null, element varchar2 := null) return number static procedure schemavalidate(instance xmltype) Überprüfen/manuelles Setzen des Validierungsstatus member function isschemavalidated() return number member procedure setschemavalidated(flag IN BINARY_INTEGER := 1) Christian Senger/Andreas Schmidt XMLType 23/32
Validierung Überprüfung durch Instanzenmethode isschemavalid(...)): -- manuelles Überprüfen des Datensatzes -- declare xmldoc xmltype; begin select document into xmldoc from person_schema_xml x where existsnode(document,'/person[@id="243"]')=1; IF xmldoc.isschemavalid() = 1 THEN -- hier erfolgt die Validierung dbms_output.put_line('dokument wurde nicht beanstantet'); ELSE dbms_output.put_line('dokument wurde als falsch erkannt'); END IF; end; / show errors Christian Senger/Andreas Schmidt XMLType 24/32
Validierung Überprüfung mittels Trigger: CREATE TRIGGER is_valid_trig BEFORE INSERT OR UPDATE ON person_schema_xml FOR EACH ROW DECLARE newxml XMLType; BEGIn newxml := :new.document; XMLTYPE.schemaValidate(newxml); END; / Christian Senger/Andreas Schmidt XMLType 25/32
XMLType und XQuery Zugriff auf Tabellen/Views mit Spalten vom Typ XMLType: 1.Schritt: Anlegen eines Views mit XMLType Spalte Test: create or replace view kleinstaaten (document) as select xmlelement("land", xmlattributes(code as "ID"), xmlforest(capital, population)) from mondial.country c where population < 100000; select document from kleinstaaten; Ausgabe (Instanzen vom Typ XMLType): <LAND ID="AND"><CAPITAL>Andorra la Vella</CAPITAL><POPULATION>72766</POPULATION></LAND> <LAND ID="FL"><CAPITAL>Vaduz</CAPITAL><POPULATION>31122</POPULATION></LAND> <LAND ID="MC"><CAPITAL>Monaco</CAPITAL><POPULATION>31719</POPULATION></LAND>... 15 Zeilen ausgewählt. Christian Senger/Andreas Schmidt XMLType 26/32
XQuery auf Datensätze im View kleinstaaten select XMLquery('let $ks := /LAND let $stadt:=$ks/capital/text() let $id:=$ks/@id return <stadt land="{$id}">{$stadt}</stadt>' PASSING document RETURNING CONTENT) from kleinstaaten; Ausgabe (Instanzen vom Typ XMLType): <stadt land="and">andorra la Vella</stadt> <stadt land="fl">vaduz</stadt> <stadt land="mc">monaco</stadt> <stadt land="v">vatican City</stadt> <stadt land="rsm">san Marino</stadt> <stadt land="ag">saint Johns</stadt> <stadt land="wd">roseau</stadt>... Input für XMLQuery Methode ist die Spalte document des Views kleinstaaten 15 Zeilen ausgewählt Christian Senger/Andreas Schmidt XMLType 27/32
Anfrage: XMLType und XQuery select XMLquery('let $ks := /LAND let $stadt:=$ks/capital/text() let $id:=$ks/@id return <stadt land="{$id}">{$stadt}</stadt>' PASSING document RETURNING CONTENT) from kleinstaaten where existsnode(document,'/land[population > 20000]')=1 ; Ausgabe (Instanzen vom Typ XMLType): <stadt land="and">andorra la Vella</stadt> <stadt land="fl">vaduz</stadt> <stadt land="mc">monaco</stadt> <stadt land="v">vatican City</stadt> <stadt land="rsm">san Marino</stadt>... 11 Zeilen ausgewählt. Christian Senger/Andreas Schmidt XMLType 28/32
Anfrage: XMLType und XQuery select xmlagg(xmlquery('let $ks := /LAND let $stadt:=$ks/capital/text() let $id:=$ks/@id return <stadt land="{$id}">{$stadt}</stadt>' PASSING document RETURNING CONTENT)) from kleinstaaten where existsnode(document,'/land[population > 20000]')=1 ; Ausgabe (Instanz vom Typ XMLType): <stadt land="and">andorra la Vella</stadt><stadt land="fl">vaduz</stadt><stadt \ land="mc">monaco</stadt><stadt land="rsm">san Marino</stadt><stadt land="ag">saint \ Johns</stadt><stadt land="wd">roseau</stadt><stadt land="wg">saint Georges</stadt><stadt\ land="kn">basseterre</stadt><stadt land="kir">tarawa</stadt><stadt land="mh">majuro\ </stadt><stadt land="sy">victoria</stadt> 1 Zeilen ausgewählt. Christian Senger/Andreas Schmidt XMLType 29/32
Typtransformationen extract(), XMLElement(), XMLAttributes(), XMLRoot(), XMLAgg(), XMLQuery() liefern jeweils eine XMLType Instanz als Ergebnis zurück. Transformation von XMLType in konkreten Datentyp mittels folgender Methoden: getclobval(): liefert XMLType Instanz als CLOB getstringval(): Liefert XMLType-Instanz als Zeichenkette getnumberval(): Liefert Wert einer XMLType-Instanz als numerischen Wert zurück (XMLType Instanz muss Textknoten mit numerischem Inhalt sein) Beispiel: select extract(xmltype('<x>12</x>'),'/x/text()').getnumberval() from dual; -- neue Notation: -- select xmltype('<x>12</x>').extract('/x/text()').getnumberval() Christian Senger/Andreas Schmidt XMLType 30/32
Literatur/Quellen: Anlegen von typisierten Views: http://www.stanford.edu/dept/itss/docs/oracle/10g/appdev.101/b10790/xdb14vie.htm Querying, Constructing, and Transforming XML with Oracle XQuery http://www.oracle.com/technology/pub/articles/vasiliev_xquery.html Towards an industrial strength SQL/XML Infrastructure http://www.oracle.com/technology/tech/xml/xquery/pdf/ ICDE2005_industrial_strength_sqlxml.pdf Leseproben xquery buch (dpunkt verlag) http://www.dpunkt.de/buch/3-89864-266-6.html How To: Oracle XML DB: http://www.doag.org/pub/docs/konferenz/2004/vortraege/oraclexmldb.pdf oracle-faq: http://www.orafaq.com/faqxml.htm Christian Senger/Andreas Schmidt XMLType 31/32
Literatur/Resourcen XML in der oracle-datenbank - relational and beyond: http://doesen0.informatik.uni-leipzig.de/proceedings/paper/ip6.pdf Oracle, Java, XML - Integration in Oracle9iM; Rudolf Jansen ; Software & Support Verlag GmbH; 2004; 60 Seiten; ISBN 3-935042-33-7; Preis: 39.90 EUR XML & Datenbanken - Konzepte, Sprachen und Systeme; Meike Klettke / Holger Meyer; dpunkt.verlag; Dezember 2002; 444 Seiten, Broschur; 42 Euro; ISBN 3-89864-148-1 XMLType: http://download.oracle.com/docs/cd/b19306_01/appdev.102/b14258/t_xml.htm Vorlesung (inkl. Skript) Einführung in XML (Prof. Wegner, Uni Kassel) http://www.db.informatik.uni-kassel.de/lehre/ws0405/xml Christian Senger/Andreas Schmidt XMLType 32/32