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:
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.
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.
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
We still assume that this is our example XML file:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>Our first select will find all team names and locations:
<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>
-- table: IMP_FMWhat are we doing here?
-- 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
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,What are we doing here?
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
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"?>To select the data now is a bit more complicated:
<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>
What are we doing here?
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
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