1

I have a CLOB column in my table which contains an XML. I want to fetch the xml after a specific tag to its ending tag i.e

Full XML in CLOB column

<ParentTag>
 <Location>ABC XYZ ....</Location>
 <Person>
  <Name>Mohsin</Name>
  <Age>23</Age>
 </Person>
</ParentTag>

What I am trying to fetch is something like this:

<Person>
  <Name>Mohsin</Name>
  <Age>23</Age>
</Person>

I have tried to use dbms_lob.substr and dbms_lob.getlength but that doesnt help as the sub XML may contain the <Person> tag starting at different bytes in different scenarios.

Any help would be greatly appreciated. Thanks

1 Answer 1

4

Don't try to parse the node out yourself with substrings. Oracle has extensive XML support built-in. You can do this with an XMLQuery:

select xmlquery('/ParentTag/Person' passing xmltype(xml_clob) returning content)
  as xml_value
from your_table;

XML_VALUE                                                                      
--------------------------------------------------------------------------------
<Person><Name>Mohsin</Name><Age>23</Age></Person>

If your XML document (in the CLOB) can have multiple person nodes then you can use XMLTable instead to extract them all.

And if you want it to be a formatted string matching what you've shown, rather than an XML document, you can use an XMLSerialize wrapper call:

select xmlserialize(content
  xmlquery('/ParentTag/Person' passing xmltype(xml_clob) returning content)
    as varchar2(100) indent size=2) as string_value
from your_table;

STRING_VALUE                                                                   
--------------------------------------------------------------------------------
<Person>                                                                        
  <Name>Mohsin</Name>                                                           
  <Age>23</Age>                                                                 
</Person>

Following up a comment, if you have anamespace you can declare that as part of the XPath:

select xmlquery('declare namespace NS4 = "http://soa.comptel.com/2011/02/instantlink"; /ParentTag/NS4:Person'
  passing xmltype(prov_request) returning content) as xml_value
from your_table;

select xmlserialize(content
  xmlquery('declare namespace NS4 = "http://soa.comptel.com/2011/02/instantlink"; /ParentTag/NS4:Person'
      passing xmltype(prov_request) returning content)
    as varchar2(150) indent size=2) as string_value
from your_table;

The extracted Person node will still have that namespace information though:

STRING_VALUE                                                                   
--------------------------------------------------------------------------------
<NS4:Person xmlns:NS4="http://soa.comptel.com/2011/02/instantlink">             
  <NS4:Name>Mohsin</NS4:Name>                                                   
  <NS4:Age>23</NS4:Age>                                                         
</NS4:Person>
Sign up to request clarification or add additional context in comments.

3 Comments

Hi alex, Thank you very much for the answer. Pardon me to miss out on namespaces. I have namespace on the <Person> tag.
like this: code <ParentTag> <Location>ABC XYZ ....</Location> <NS4:Person xmlns:NS4="http://soa.comptel.com/2011/02/instantlink"> <NS4:Name>Mohsin</NS4:Name> <NS4:Age>23</NS4:Age> </NS4:Person> </ParentTag> I have tried using code passing xmltype(prov_request) returning content) but i am unable to get the desired result.
@user3081780 - updated with a version that handles the namespace.

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.