Quantcast
Channel: APEX-AT-WORK by Tobias Arnhold
Viewing all articles
Browse latest Browse all 177

Working with XML files and APEX - Part 2: Selecting data from XMLType with XMLTable

$
0
0
After we successfully imported XML files into our APEX application. It's time to start to analyze them.

We still assume that this is our example XML file:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<leagues>
<league id="1" name="2. Bundeliga">
<teams>
<team>
<id>1</id>
<name location="Dresden" stadium="Glücksgas-Stadion">SG Dynamo Dresden</name>
</team>
<team>
<id>2</id>
<name location="Cologne" stadium="RheinEnergieStadion">1. FC Köln</name>
</team>
<team>
<id>3</id>
<name location="Berlin" stadium="Alte Försterei">1. FC Union Berlin</name>
</team>
<team>
<id>4</id>
<name location="Düsseldorf" stadium="Esprit Arena">Fortuna Düsseldorf</name>
</team>
</teams>
</league>
</leagues>
Our first select will find all team names and locations:
-- table: IMP_FM
-- XMLType column: XML_FILE

SELECT T.TEAM,
T.LOCATION
FROM
IMP_FM FM,
XMLTable('/leagues/league/teams/team/name' PASSING FM.XML_FILE
COLUMNS "TEAM" VARCHAR2(255) PATH 'text()',
"LOCATION" VARCHAR2(255) PATH '@location'
) T
What are we doing here?
In the FROM-clause we set our XML table "IMP_FM" and then we generate a new XMLTable object. Inside this object we define the start entry "/leagues/league/teams/team/name" from where we want to select our data. In the PASSING-clause we define the XMLType column from where our data is coming.
Next step is to set the SQL columns based on the XML data.
To get the team names we need to select the text from the xml element "name". To do that we use the function "text()".
To select the attribute "location" we need to use an "@" in front of the attribute name.
 This newly created table will have the name "T" and can be selected in the SELECT-clause.

In the next example we will select league and team names. Actually they would be two tables with an 1-n relationship. Because of that we have to implement two XMLTable objects in our select.
SELECT L.LEAGUE,
T.TEAM,
T.LOCATION
FROM
IMP_FM FM,
XMLTable('/leagues/league' PASSING FM.XML_FILE
COLUMNS "LEAGUE" VARCHAR2(255) PATH '@name',
"T_XML" XMLTYPE PATH 'teams/team'
) L,
XMLTable('team/name' PASSING L.T_XML
COLUMNS "TEAM" VARCHAR2(255) PATH 'text()',
"LOCATION" VARCHAR2(255) PATH '@location'
) T
What are we doing here?
In our first XMLTable object we generate a XMLType column with the data from path "teams/team". This column is named as "T_XML". The generated table is named as "L".
Now we create a new XMLTable object based on the data of our XMLType column "L.T_XML". We follow the same logic as in first select and just use a shorter PATH "team/name".
More information about XML sub-selects can be found in this blog post: New 12c XMLTABLE’s “RETURNING SEQUENCE BY REF” clause

In the last example I want to show the work with namespaces. For that our XML changes a bit.
<?xml version="1.0" encoding="UTF-8"?>
<leagues xmlns:tt="http://www.footballleagues_xml.org/schemas/team" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.footballleagues_xml.org/schemas http://www.footballleagues_xml.org/schemas/xml/XML.xsd" version="2.1" xmlns="http://www.footballleagues_xml.org/schemas">
<league id="1" name="2. Bundeliga">
<teams>
<team>
<tt:id>1</tt:id>
<tt:name location="Dresden" stadium="Glücksgas-Stadion">SG Dynamo Dresden</tt:name>
</team>
<team>
<tt:id>2</tt:id>
<tt:name location="Cologne" stadium="RheinEnergieStadion">1. FC Köln</tt:name>
</team>
<team>
<tt:id>3</tt:id>
<tt:name location="Berlin" stadium="Alte Försterei">1. FC Union Berlin</tt:name>
</team>
<team>
<tt:id>4</tt:id>
<tt:name location="Düsseldorf" stadium="Esprit Arena">Fortuna Düsseldorf</tt:name>
</team>
</teams>
</league>
</leagues>
To select the data now is a bit more complicated:

SELECT T.TEAM,
T.LOCATION
FROM
IMP_FM FM,
XMLTable(XMLNameSpaces('http://www.footballleagues_xml.org/schemas/team' as "tt",
default 'http://www.footballleagues_xml.org/schemas'),
'/leagues/league/teams/team' PASSING FM.XML_FILE
COLUMNS "TEAM" VARCHAR2(255) PATH 'tt:name/text()',
"LOCATION" VARCHAR2(255) PATH 'tt:name/@location'
) T
What are we doing here?
Inside the XMLTable object we define a "XMLNameSpace" which is marked as "tt".
Inside our column definition we use "tt:" to select our data.
More information about multiple Namespaces can be found here: https://forums.oracle.com/thread/2381998

That's it for today. Cheers Tobias

Viewing all articles
Browse latest Browse all 177

Trending Articles