Search Oracle Blogs

List of Blogs maintained by Paweł Barut.


Tuesday, November 07, 2006

XMLType and Namespace problem

I've run into some strange problem with XMLType and XML namespaces. I'll try to make a showcase. Lets define variable and simple XML content
SQL> var x varchar2(200);
SQL> exec :x := '<feed
xmlns="http://www.w3.org/2005/Atom"><id>test_id</id></feed>'
PL/SQL procedure successfully completed.
Try to find out what tag is on root:
SQL> select XMLType(:x).getRootElement() from dual;
XMLTYPE(:X).GETROOTELEMENT()
--------------------------------------------------------------------------------
feed
Lets find out the namespace:
SQL> select XMLType(:x).getNamespace() from dual;
XMLTYPE(:X).GETNAMESPACE()
--------------------------------------------------------------------------------
Seems to be no namespace. But there was namespace in XML definition. Lets try extract data:
SQL> select XMLType(:x).extract('/feed').getStringVal() from dual;
XMLTYPE(:X).EXTRACT('/FEED').GETSTRINGVAL()
--------------------------------------------------------------------------------
So nothing was extracted. It's not what I was expecting. Ok, lets try to force namespace:
SQL> select XMLType(:x).extract('/feed',
'xmlns="http://www.w3.org/2005/Atom"').getStringVal() from dual;
XMLTYPE(:X).EXTRACT('/FEED','XMLNS="HTTP://WWW.W3.ORG/2005/ATOM"').GETSTRINGVAL(
--------------------------------------------------------------------------------
<feed
xmlns="http://www.w3.org/2005/Atom"> <id>test_id</id>
</feed>
Now works fine.
For me it is little confusing: there is no namespace, but you must provide namespace if you want to extract data.
Paweł

3 comments:

Anonymous said...

I ran into similar problems - getnamespace does not seem to return a value (using 9i)

My biggest problem is that I get an XML from a WebService containing nodes with the default namespace "" ( e.g. <number xmlns="">12</number>) and it is not possible to extract this element.

Paweł Barut said...

i've solved it once using code like this:
declare
xml_str CLOB;
xml XMLType;
begin
...
xml_str := xml.getCLOBval();
xml_str := regexp_replace(xml_str, 'xmlns:.*".*"', '');
xml_str := regexp_replace(xml_str, 'xsi:', '');
xml_str := regexp_replace(xml_str, 'ns[0-9]*:', '');
xml_str := regexp_replace(xml_str, 'soapenc:', '');
xml_str := regexp_replace(xml_str, 'soapenv:', '');
xml := xmltype(xml_str);
...
end;

But, i'm not proud of this solution. If anybody knows more elegant solution, please let me know.

Anonymous said...

xml_ret := xml_ret.extract('//string/text()','xmlns="http://tempuri.org/"');

this works

but below statement doesn't

xml_ret := xml_ret.extract('//string/text()');

 

Copyright © Paweł Barut
Printing from DOS to USB Printer