Reputation: 33
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
Upvotes: 1
Views: 1282
Reputation: 191275
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>
Upvotes: 4