This tutorial shows how to extract values from strings of XML elements like this one
DATA_SET STRING ------------------------- ---------------------------------------- XML - 2 <V1>a</V1> <V2>b,b</V2> <V3>c c c</V3>
and return the values in separate columns like this.
DATA_SET VAL_1 VAL_2 VAL_3 ------------------------- ------ ------ ------ XML - 2 a b,b c c c
Warning: The snippets in this tutorial do not work as expected when the source data contains NULL values (as tested in Oracle 10g XE, see the Gotchas section of the XML Values - 1 tutorial). NULL values have therefore been excluded from the test data.
In the
XML Values - 1
tutorial we saw solutions for extracting values from XML fragments when each element in the fragment had
the same name.
Below we will see how slight modifications of those solutions are used to extract values from
XML fragments when the element names differ from each other.
In each case the only change needed is to replace XPath expressions like
/V[1]/text()
with expressions like
/V1/text()
Extracting Values with the EXTRACT and GETSTRINGVAL Member Functions
SQL Solution
select
t1_xml_2a.num ,
t1_xml_2a.xml_instance ,
t1_xml_2a.xml_instance.extract('/V1/text()').getstringval() as val_1 ,
t1_xml_2a.xml_instance.extract('/V2/text()').getstringval() as val_2 ,
t1_xml_2a.xml_instance.extract('/V3/text()').getstringval() as val_3
from
( select num, xmlparse( content string wellformed ) as xml_instance
from t1_xml_2
) t1_xml_2a
order by num ;
NUM XML_INSTANCE VAL_1 VAL_2 VAL_3 ---- ---------------------------------------- ------ ------ ------ 1 <V1>a</V1> a 2 <V1>a</V1> <V2></V2> a 3 <V1>a</V1> <V2></V2> <V3></V3> a 4 <V1></V1> <V2>b,b</V2> <V3></V3> b,b 5 <V1></V1> <V2></V2> <V3>c c c</V3> c c c 6 <V1>a</V1> <V2>b,b</V2> a b,b 7 <V1>a</V1> <V2>b,b</V2> <V3></V3> a b,b 8 <V1>a</V1> <V2>b,b</V2> <V3>c c c</V3> a b,b c c c 9 <V1></V1> 10 <V1></V1> <V2></V2> 11 <V1></V1> <V2></V2> <V3></V3>
PL/SQL Solutions
begin
dbms_output.put_line( '
num VAL_1 VAL_2 VAL_3
---------- ---------- ---------- ----------
' );
for t1_xml_2_row in
( select
t1_xml_2a.num ,
t1_xml_2a.xml_instance ,
t1_xml_2a.xml_instance.EXTRACT('/V1/text()').GETSTRINGVAL() as val_1 ,
t1_xml_2a.xml_instance.EXTRACT('/V2/text()').GETSTRINGVAL() as val_2 ,
t1_xml_2a.xml_instance.EXTRACT('/V3/text()').GETSTRINGVAL() as val_3
from
( select t1_xml_2.num, xmlparse(content t1_xml_2.string wellformed) as xml_instance
from t1_xml_2
) t1_xml_2a
order by num
) loop
dbms_output.put_line
( rpad( t1_xml_2_row.num, 11 ) ||
rpad( nvl( t1_xml_2_row.val_1, ' ' ), 11 ) ||
rpad( nvl( t1_xml_2_row.val_2, ' ' ), 11 ) ||
rpad( nvl( t1_xml_2_row.val_3, ' ' ), 11 )
);
end loop;
end;
/
num VAL_1 VAL_2 VAL_3
---------- ---------- ---------- ----------
1 a
2 a
3 a
4 b,b
5 c c c
6 a b,b
7 a b,b
8 a b,b c c c
9
10
11
begin
dbms_output.put_line( '
num VAL_1 VAL_2 VAL_3
---------- ---------- ---------- ----------
' );
for t1_xml_2_row in
( select num, xmlparse( content string wellformed ) as xml_instance
from t1_xml_2
order by num
) loop
declare
x_val_1 xmltype := t1_xml_2_row.xml_instance.extract('/V1/text()') ;
x_val_2 xmltype := t1_xml_2_row.xml_instance.extract('/V2/text()') ;
x_val_3 xmltype := t1_xml_2_row.xml_instance.extract('/V3/text()') ;
val_1 varchar2(10) :=
CASE when x_val_1 is null then null else x_val_1.getStringVal() end ;
val_2 varchar2(10) :=
CASE when x_val_2 is null then null else x_val_2.getStringVal() end ;
val_3 varchar2(10) :=
CASE when x_val_3 is null then null else x_val_3.getStringVal() end ;
begin
dbms_output.put_line
( rpad( t1_xml_2_row.num, 11 ) ||
rpad( nvl( val_1, ' ' ), 11 ) ||
rpad( nvl( val_2, ' ' ), 11 ) ||
rpad( nvl( val_3, ' ' ), 11 )
);
end;
end loop;
end;
/
num VAL_1 VAL_2 VAL_3
---------- ---------- ---------- ----------
1 a
2 a
3 a
4 b,b
5 c c c
6 a b,b
7 a b,b
8 a b,b c c c
9
10
11
Extracting Numbers with the EXTRACT and GETNUMBERVAL Member Functions
column n_val_1 format 999999
column n_val_2 format 999999
column n_val_3 format 999999
select
t1_xml_3.num ,
t1_xml_3.xml_instance ,
t1_xml_3.xml_instance.extract('/V1/text()').GETNUMBERVAL() as N_VAL_1 ,
t1_xml_3.xml_instance.extract('/V2/text()').GETNUMBERVAL() as N_VAL_2 ,
t1_xml_3.xml_instance.extract('/V3/text()').GETNUMBERVAL() as N_VAL_3
from
( select
1 as num,
xmlparse(content '<V1>5</V1> <V2></V2> <V3>46</V3>' wellformed) as xml_instance
from dual
) t1_xml_3
;
NUM XML_INSTANCE N_VAL_1 N_VAL_2 N_VAL_3 ---- ---------------------------------------- ------- ------- ------- 1 <V1>5</V1> <V2></V2> <V3>46</V3> 5 46
Extracting Values With the SQL EXTRACTVALUE Function
select
t1_xml_2a.num ,
t1_xml_2a.xml_instance ,
EXTRACTVALUE( t1_xml_2a.xml_instance, '/V1/text()' ) as VAL_1 ,
EXTRACTVALUE( t1_xml_2a.xml_instance, '/V2/text()' ) as VAL_2 ,
EXTRACTVALUE( t1_xml_2a.xml_instance, '/V3/text()' ) as VAL_3
from
( select num, xmlparse( content string wellformed ) as xml_instance
from t1_xml_2
) t1_xml_2a
order by num ;
NUM XML_INSTANCE VAL_1 VAL_2 VAL_3 ---- ---------------------------------------- ------ ------ ------ 1 <V1>a</V1> a 2 <V1>a</V1> <V2></V2> a 3 <V1>a</V1> <V2></V2> <V3></V3> a 4 <V1></V1> <V2>b,b</V2> <V3></V3> b,b 5 <V1></V1> <V2></V2> <V3>c c c</V3> c c c 6 <V1>a</V1> <V2>b,b</V2> a b,b 7 <V1>a</V1> <V2>b,b</V2> <V3></V3> a b,b 8 <V1>a</V1> <V2>b,b</V2> <V3>c c c</V3> a b,b c c c 9 <V1></V1> 10 <V1></V1> <V2></V2> 11 <V1></V1> <V2></V2> <V3></V3>
