简体   繁体   中英

Parsing Nested XML with Namespaces in PLSQL

I have an xml that looks like below

<ibm:dept bldg="123" xmlns:ibm="http://www.ibm.com/xmltable">
  <ibm:employee id="144">
    <ibm:name>
      <ibm:first>James</ibm:first>
      <ibm:last>Bond</ibm:last>
    </ibm:name>
    <ibm:office>007</ibm:office>
    <ibm:phone>905-007-1007</ibm:phone>
    <ibm:salary currency="USD">77007</ibm:salary>
  </ibm:employee>
</ibm:dept>'

I am trying to parse it using XMLTable function. This is what I have tried -

select x.*,
       y.*
 from xml_tab t,
 XMLTable(XMLnamespaces('http://www.ibm.com/xmltable' as "ibm"),
 'ibm:dept/ibm:employee' 
 passing t.xml_data
 columns 
        empid NUMBER path '@id',
        office VARCHAR2(5) path 'ibm:office',
        name XMLTYPE path 'ibm:name' 
 ) x,
 XMLTable(
 'ibm:name'
 passing x.name 
     columns 
            firstname VARCHAR2(10) path 'ibm:first',
            lastname VARCHAR2(10) path 'ibm:last') y
 where t.id =3;

However it's errored out with below error

ORA-19228: XPST0008 - undeclared identifier: prefix 'ibm' local-name 'ibm:name'

Hoping someone could explain the error. cheers!

Data Set up

create table xml_tab
(
 id NUMBER,
 xml_data XMLType
 );



insert into xml_tab
values(3, XMLType.createXML('<ibm:dept bldg="123" xmlns:ibm="http://www.ibm.com/xmltable">
  <ibm:employee id="144">
    <ibm:name>
      <ibm:first>James</ibm:first>
      <ibm:last>Bond</ibm:last>
    </ibm:name>
    <ibm:office>007</ibm:office>
    <ibm:phone>905-007-1007</ibm:phone>
    <ibm:salary currency="USD">77007</ibm:salary>
  </ibm:employee>
</ibm:dept>'));

If you want to use qualified names in the PATH expressions of the COLUMNS clause, then you need to specify the XMLNAMESPACES clause ( Doc. ).

So you need to individually define XMLnamespaces even for the second XMLTable

( alias might change such as ibm2 for the second table by replacing all ibm: by ibm2: ) :

select x.*, y.*
  from xml_tab t,
       XMLTable(XMLnamespaces('http://www.ibm.com/xmltable' as "ibm"),
                'ibm:dept/ibm:employee' passing t.xml_data columns empid
                NUMBER path '@id',
                office VARCHAR2(5) path 'ibm:office',
                name XMLTYPE path 'ibm:name') x,
       XMLTable(XMLnamespaces('http://www.ibm.com/xmltable' as "ibm"),
                'ibm:name' passing x.name columns firstname VARCHAR2(10) path
                'ibm:first',
                lastname VARCHAR2(10) path 'ibm:last') y                
 where t.id = 3;

Demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM