Arbeiten mit XML in Application Express
Erscheinungsmonat |
APEX-Version |
Datenbankversion |
Mai 2013 |
alle |
ab 10.2 |
Mit XML kommt man als APEX-Entwickler immer wieder in Kontakt. Und ob
man XML erzeugen, zerlegen, prüfen oder anzeigen muss: Die Oracle-Datenbank
bietet zahlreiche Funktionen, Packages und Werkzeuge zum Umgang mit XML an,
die man aus APEX heraus auch sehr einfach nutzen kann. Dieser Community-Tipp
widmet sich dem Thema und stellt vor, wie man verschiedenste Aufgabenstellungen
rund um XML mit der Datenbank erledigen kann. Zur besseren Demonstration werden
alle XML-Funktionen anhand von Formularen oder Berichten vorgestellt - natürlich
ist die Anwendung in PL/SQL-Logik oder APEX-Prozessen ebenso möglich.
XML hochladen und in einer Tabelle speichern
Alles beginnt damit, dass ein XML-Dokument über eine APEX-Anwendung in
eine Tabelle hochgeladen wird. Das interessante wird dabei sein, von einem
BLOB (als solcher taucht eine hochgeladene Datei in APEX auf) zu einem XMLTYPE (dem Datentypen für
XML) zu kommen.
Erstellen
Sie also zuerst eine Tabelle, in die die XML-Dateien gespeichert werden sollen. Dabei
nehmen wir für die Dokumente selbst nicht etwa CLOB oder BLOB, sondern eben
den Datentypen, den die Datenbank dafür vorsieht: XMLTYPE.
In der Oracle-Datenbank ist XML nicht gleich XML. Es wird zwar stets der Datentyp XMLTYPE
verwendet, dieser bietet aber drei Varianten zur konkreten Speicherung an:
Textbasiert, Objektrelational und (ab Oracle 11g) Binary XML. Eine genaue Betrachtung
dieser Varianten würde den Rahmen dieses Artikels sprengen - wer interessiert ist, findet
dazu hier ausführliche Informationen.
In diesem Tipp verwenden wir die flexibelste Variante Binary XML, die aber erst
ab Oracle11g zur Verfügung steht. In Oracle10g müssen Sie das CREATE TABLE-Kommando
durch das folgende ersetzen.
Dann brauchen Sie eine APEX-Anwendung und darin eine Seite zum Hochladen von XML-Dateien. Stellen
Sie die Sprache der Anwendung (Globalization) für diesen Tipp am besten auf Englisch ein;
das macht den späteren Umgang mit den XML-Beispieldateien wegen des Zahlenformats leichter. Auf der Seite
zum Hochladen erstellen Sie
ein Element vom Typ File Browse, eine Schaltfläche zum Absenden und ein
Textfeld für den Dokumentzeichensatz (daraus kann man natürlich auch eine Auswahlliste machen).
Stellen Sie beim Element zum File-Upload ein, dass die Datei nach WWV_FLOW_FILES
geladen werden soll (Abbildung 1) - ein direktes Laden in die XML-Tabelle ist nicht möglich.
Die Seite sollte dann in etwa wie in Abbildung 2 aussehen ...
Abbildung 1: Die hochgeladenen XML-Dateien werden (zunächst) nach "WWV_FLOW_FILES" geladen
Abbildung 2: Anwendungsseite zum Upload von XML-Dokumenten
Als nächstes erstellen Sie den PL/SQL-Seitenprozess, der die XML-Datei
von der Tabelle WWV_FLOW_FILES nach TAB_XML_DOKUMENTE kopiert und dabei
aus dem BLOB einen XMLTYPE macht. Und für diesen Prozess benötigen wir
das zusätzliche Formularelement für den Dokumentzeichensatz. Diese Information ist zwar eigentlich
auch in der XML-Datei selbst vorhanden, aber in vielen Fällen ist der "XML-Prolog"
falsch oder fehlt völlig. Erzeugen Sie also einen neuen onSubmit-Prozess,
der bei Klick auf die Schaltfläche ausgeführt werden soll und folgenden PL/SQL-Code
enthält.
Versehen Sie den Prozess dann noch mit Erfolgs- und Fehlermeldungen und sorgen Sie
dafür, dass er nur dann ausgeführt wird, wenn die Schaltfläche UPLOAD geklickt wurde. Bevor
Sie nun etwas hochladen, legen Sie noch einen Bericht an, der unterhalb des Upload-Formulars
dargestellt werden soll - er soll eine Übersicht über die Inhalte der Tabelle geben. Nehmen
Sie dazu folgendes Berichts-SQL.
Damit ist die Upload-Seite fertig. Nehmen Sie nun also ein XML-Dokument (zum Beispiel
ADAMS-20011127121040988PST.xml) und laden Sie es hoch (Abbildung 3). Tragen Sie AL32UTF8 als Encoding ein.
Abbildung 3: Ein XML-Dokument wurde hochgeladen
Nun befindet sich also ein XML-Dokument in der Tabelle. Der nächste Schritt
wäre, die XML-Inhalte auf einer anderen APEX-Seite anzuzeigen. Den bereits
vorhandenen Bericht können wir zur Auswahl des anzuzeigenden Dokuments verwenden;
verlinken Sie dazu die Berichtsspalte ID mit der nächsten APEX-Seite, wie in
Abbildung 4 dargestellt ...
Abbildung 4: Verlinkung der Berichtsspalte "ID" mit der APEX-Seite zum Darstellen des XML
Auf der APEX-Seite 3 legen Sie nun ein verstecktes Element (Hidden Item) namens
P3_ID an, danach geht es an die Darstellung des XML-Dokumentes ...
XML-Dokumente auf APEX-Seiten anzeigen
Der erste Versuch, das XML in APEX zur Anzeige zu bringen, wäre ein recht
einfacher Bericht mit folgender SQL-Abfrage:
Das Ergebnis kann, wie Abbildung 5 zeigt, nicht wirklich zufriedenstellen ...
Abbildung 5: XMLTYPE-Tabellenspalten können nicht direkt in einem APEX-Bericht angezeigt werden
Eine Tabellenspalte vom Typ XMLTYPE kann von einem APEX-Bericht nicht ohne weiteres
angezeigt werden. Das XML muss zunächst in Zeichendaten (also in einen CLOB) umgewandelt
werden. Im Internet findet man hierfür recht häufig die Funktion GETCLOBVAL(), diese
ist aber veraltet - ab Oracle11g ist
XMLSERIALIZE die richtige. Zunächst also das
Berichts-SQL für Oracle10g ...
... und dann das für Oracle11g ...
Man sieht der Syntax schon an, dass die XMLSERIALIZE-Funktion einige Möglichkeiten
anbietet, die Ausgabe zu steuern - so kann man mit INDENT SIZE bzw. NO INDENT steuern,
ob das XML mit Einrückungen oder ohne dargestellt werden soll (Pretty Printing), daneben
können auch Parameter zum Steuern des sog. XML-Prologs verwendet werden.
Abbildung 6: Der XMLTYPE wird nun dargestellt
Abbildung 6 zeigt, dass das XML nun dargestellt werden kann; für APEX ist es ja
auch gar kein XML mehr, sondern ein CLOB - und den kann ein APEX-Bericht ja problemlos
anzeigen. Während die XML-Tags korrekt mit ihren spitzen Klammern dargestellt werden, klappt
das mit den Zeilenumbrüchen und den Einrückungen noch nicht so richtig - aber dies
lässt sich leicht in den Griff bekommen. Navigieren Sie dazu zu den Eigenschaften
der Berichtsspalte, dort zu HTML-Ausdruck und dort tragen Sie ein: <pre>#XML#</pre>
(Abbildung 7). Damit wird das XML in ein HTML-Tag <pre> eingebaut - der Browser
wird nun alle Zeilenumbrüche und Leerzeichen so darstellen, wie sie im XML-"Quellcode"
vorkommen.
Abbildung 7: Eintragen eines "HTML-Ausdrucks" für die Berichtsspalte
Bevor Sie sich den Bericht nochmals ansehen, stellen Sie außerdem noch Strip HTML im Bereich der Berichtsattribute
auf No um (Abbildung 8), damit auch wirklich alle Tags dargestellt werden.
Abbildung 8: "Strip HTML" abschalten
Nun können Sie das XML-Dokument im Browser betrachten ...
Abbildung 9: Darstellung des XML-Dokuments auf einer APEX-Seite
Einzelne XML-Tags extrahieren und als Bericht darstellen
In den meisten Fällen möchte man jedoch nicht den XML-Quelltext auf der
APEX-Seite darstellen, sondern die Inhalte der XML-Tags aufbereiten - und auch
hierfür bietet die Datenbank SQL-Funktionen an. Sie können zu jedem beliebigen
XML-Tag navigieren (dabei sogar die XML-Hierarchie durchlaufen), den Inhalt
"ausschneiden" und wie eine normale, relationale Tabelle darstellen.
Erzeugen Sie also nochmals eine neue APEX-Seite und auf dieser wiederum einen
neuen Bericht. Zunächst sollen die XML "Kopfdaten" angezeigt werden, also die, die
nur einmal pro Dokument vorkommen. Die SQL-Funktion
XMLTABLE dient zum Extrahieren
einzelner XML-Tags. Verwenden Sie die folgende SQL-Abfrage ...
Das "Mapping" der XML-Tags auf die Ergebnisspalten der Abfrage ist in der
COLUMNS-Klausel sehr gut erkennbar. Abbildung 10 zeigt das Ergebnis des
Berichts (nachdem noch zwei weitere XML-Dokumente,
ALLEN-20011127121048799PST.xml oder
BLAKE-20011127121045143PST.xml,
hochgeladen wurden).
Abbildung 10: XML-Inhalte: aufbereitet als normaler Bericht
Auch die Inhalte des mehrfach vorkommenden XML-Tags LineItem können in einem
APEX-Bericht aufbereitet werden - allerdings sind nun zwei, miteinander verbundene,
XMLTABLE-Ausdrücke nötig ...
In der COLUMNS-Klausel des ersten XMLTABLE-Ausdrucks wird nun zusätzlich
die Spalte LINEITEMS vom Typ XMLTYPE festgelegt. Diese enthält den gesamten
XML-Abschnitt mit den (mehrfach vorkommenden) "LineItems". Dieser wird nun im
zweiten XMLTABLE-Ausdruck als eigenes XML-Dokument aufgefasst, zerlegt und wiederum
auf Ergebnisspalten abgebildet. Die SQL-Abfrage liefert nun auch nicht mehr
eine Zeile pro XML-Dokument zurück, sondern eine pro "LineItem" - der Bericht
enthält also wesentlich mehr Zeilen. Für diese Abfrage wäre ein interaktiver
Bericht am besten geeignet (Abbildung 11).
Abbildung 11: Bericht auf Ebene der "LineItems": Das XML wurde noch weiter zerlegt
Es ist einleuchtend, dass man nun, mit den Mitteln von SQL, beliebig auf den Daten
des XML-Dokuments arbeiten kann. Dessen Inhalte lassen sich auffassen wie eine normale
Tabelle - und damit bieten sich auch alle Möglichkeiten einer normalen Tabelle.
Stylesheet Transformationen: XSLT
Eine der Eigenschaften von XML ist, dass es sich durch Stylesheet Transformationen
in andere Ausgabeformate umwandeln lässt - und diese Stylesheets werden wiederum
in einer standardisierten XML-Notation kodiert. Häufig liegen bereits fertige
XSLT-Stylesheets vor - wie auch für diesen Community-Tipp. Laden Sie also die Dateien
render-html.xsl (funktioniert nur mit diesen "PurchaseOrder"-XML-Dokumenten) und
render-xml.xsl (funktioniert mit allen XML-Dokumenten) zunächst
auf Ihren Rechner herunter und speichern Sie diese dann in Ihrem APEX Workspace
als Statische Datei ab.
Abbildung 12: XSLT-Stylesheets als "Statische Dateien" speichern
Eine "Stylesheet-Transformation" können Sie in der Datenbank mit der SQL-Funktion
XMLTRANSFORM ausführen. XMLTRANSFORM nimmt zwei Parameter entgegen: Im ersten
Parameter wird das umzuwandelnde XML-Dokument, im zweiten das XSLT-Stylesheet
(beide als XMLTYPE) übergeben. Zurückgegeben wird wiederum ein XMLTYPE. Mit dem bisher
gelernten können wir also eine SQL-Abfrage als Berichtsquelle formulieren, welche
beide Dokumente liest, die Stylesheet-Transformation durchführt und das Ergebnis
anzeigt.
Ist Ihnen aufgefallen, dass wir den Namen des Stylesheets in der SQL-Abfrage
als APEX-Item (P5_XSL_FILE) kodiert haben? Damit können wir
das XML-Dokument auf der Anwendungsseite - einfach per Auswahlliste - unterschiedlich
ausgeben lassen. Erzeugen Sie nun eine neue APEX-Anwendungsseite mit folgenden Komponenten:
- Eine Region vom Typ HTML , welche die beiden folgenden Elemente aufnimmt.
- Ein Element namens P5_ID als Auswahlliste: Nehmen Sie als Wertelisten-Abfrage: "select dateiname d, id r from tab_xml_dokumente".
- Ein Element namens P5_XSL_FILE als Auswahlliste - tragen Sie als Werteliste ein: "select filename d, filename r from wwv_flow_files where filename like '%.xsl'".
- Einen "klassischen" Bericht mit obiger SQL-Abfrage. Achten Sie darauf, dass Sie unter
Page Items to Submit die beiden definierten Elemente P5_ID und P5_XSL_FILE eintragen. Stellen Sie außerdem
sicher, dass Partial Page Refresh in den Berichtsattributen aktiviert ist.
- Sorgen Sie dann noch mit einer dynamischen Aktion dafür, dass der Bericht bei
Änderung an einer der beiden Wertelisten (onChange) aktualisiert wird (refresh).
Die Seite sollte dann in etwa so aussehen ...
Abbildung 13: APEX-Seite mit einem Bericht, der das Ergebnis einer XSLT-Transformation zeigt
Wie schon im zweiten Abschnitt, als wir XML in einem
Bericht angezeigt haben, wird das XML so angezeigt, wie es ist - aber ohne Zeilenumbrüche
und Einrückungen. Diesmal ist unser Ziel aber etwas anders: Denn das Ergebnis der XSLT-Transformation
soll nicht mehr als XML dargestellt werden - der Browser soll es als HTML interpretieren. Und
das ist bekanntlich ganz einfach: Stellen Sie die Anzeigeart der Berichtsspalte in den
Spaltenattributen auf Standard Report Column um (Abbildung 14). Schalten Sie
außerdem noch die Funktion Strip HTML in den Berichtsattributen ab.
Abbildung 14: Berichtsspalte umstellen auf "Standard Report Column"
Starten Sie die Seite danach nochmal. Sie können nun sehen, dass das Ergebnis
der XSLT-Transformation nun vom Browser als HTML interpretiert wird. Und während
das erste Stylesheet (render-html.xsl) versucht, ein "Formularlayout" für das XML zu realisieren (Abbildung 15) ...
Abbildung 15: "Formularlayout" per XSLT-Transformation
... stellt render-xml.xsl das XML wieder so dar, wie es
ist - nun aber mit
Syntax Highlighting (Abbildung 16). Und dieses
XSLT-Stylesheet funktioniert mit beliebigen XML-Dokumenten - die Darstellung funktioniert
in allen Browsern.
Abbildung 16: "Syntax Highlighting" für XML mit der Datenbank und APEX
Fazit
Die Oracle-Datenbank bietet umfangreiche Funktionen zum Umgang mit XML an - und
als APEX-Entwickler können Sie all diese Funktionen ohne weiteres nutzen. Natürlich
ist es nicht immer sinnvoll, Anwendungs-Oberflächen mit solchen XML-Funktionen zu
gestalten, sehr oft wird es nötig sein, diese Funktionen in PL/SQL Paketen, Seitenprozessen
oder Computations zu verwenden. Die gute Nachricht ist, dass Sie überall, wo SQL und PL/SQL
verwendet werden können, auch die XML-Funktionen nutzen können. XML ist für APEX also
überhaupt kein Problem.
Zurück zur Community-Seite
|