1

My question is identical to this one but instead of SQL Server I am using Oracle 12.1.

I would like to extract all the name elements from the following xml document:

<ci5>
   <employee>
      <name>George Cowley</name>  
      <salary via="B">80000</salary>
   </employee>
   <employee>
      <name>William Bodie</name>  
      <salary via="C">40000</salary>
   </employee>
   <employee>
      <name>Ray Doyle</name>  
      <salary via="C">40000</salary>
   </employee>
</ci5>  

The output I want is three separate rows such as:

<name>George Cowley</name>
<name>William Bodie</name>
<name>Ray Doyle</name>

Using the following queries

SELECT XMLQUERY('ci5/employee/name' 
                  PASSING BY VALUE XMLTYPE.CREATEXML('<ci5><employee><name>George Cowley</name><salary via="B">80000</salary></employee><employee><name>William Bodie</name><salary via="C">40000</salary></employee><employee><name>Ray Doyle</name><salary via="C">40000</salary></employee></ci5>') RETURNING CONTENT) x
   FROM dual;  

 SELECT XMLQUERY('for $i in /ci5
                 return $i/employee/name'
                 PASSING BY VALUE XMLTYPE.CREATEXML('<ci5><employee><name>George Cowley</name><salary via="B">80000</salary></employee><employee><name>William Bodie</name><salary via="C">40000</salary></employee><employee><name>Ray Doyle</name><salary via="C">40000</salary></employee></ci5>') RETURNING CONTENT) x
   FROM dual;  

the names are shown, but the output is all on one line:

<name>George Cowley</name><name>William Bodie</name><name>Ray Doyle</name>

It looks like I need to use the NODE function but I don't how to use it within an Oracle context.

2 Answers 2

1

I don't think you need any xquery for this. A simple xpath expression should suffice. Here are two options. The first returns an XML sequence (separate xml nodes), the second returns as table rows:

    WITH test AS
      (SELECT xmltype('<ci5>   
    <employee>      
    <name>George Cowley</name>        
    <salary via="B">80000</salary>   
    </employee>   
    <employee>      
    <name>William Bodie</name>        
    <salary via="C">40000</salary>   
    </employee>   
    <employee>      
    <name>Ray Doyle</name>        
    <salary via="C">40000</salary>   
    </employee>
    </ci5>  ') data
      FROM dual
      )
    SELECT xmlsequence(extract(data,'/ci5/employee/name')) FROM test

WITH test AS
      (SELECT xmltype('<ci5>   
    <employee>      
    <name>George Cowley</name>        
    <salary via="B">80000</salary>   
    </employee>   
    <employee>      
    <name>William Bodie</name>        
    <salary via="C">40000</salary>   
    </employee>   
    <employee>      
    <name>Ray Doyle</name>        
    <salary via="C">40000</salary>   
    </employee>
    </ci5>  ') data
      FROM dual
      )
    SELECT extract(value(d), '*') AS name
    FROM test,
      TABLE(xmlsequence(extract(data, '/ci5/employee/name'))) d
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks I appreciate the response, I didn't want to fill up my question with cruft but the reason for using XQUERY is that I am getting up to speed with it because extract(XML) is deprecated @ 11GR2 see: docs.oracle.com/cd/E11882_01/server.112/e41084/…
0

This Oracle white paper answered the question, I needed to use XMLTABLE which

...maps the result of an XQuery evaluation into relational rows and columns...

Changing my query to use XMLTABLE

 SELECT x.ename
   FROM XMLTABLE('/ci5/employee/name'                 
                 PASSING XMLTYPE.CREATEXML('<ci5><employee><name>George Cowley</name><salary via="B">80000</salary></employee><employee><name>William Bodie</name><salary via="C">40000</salary></employee><employee><name>Ray Doyle</name><salary via="C">40000</salary></employee></ci5>') 
                 COLUMNS ename VARCHAR2(30) PATH '/name') x 

gives the following output in SQL Developer:

enter image description here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.