Shaun Kinnair
Shaun Kinnair

Reputation: 535

Getting XML values from a Oracle CLOB database column

By using either PL/SQL or SQL I'm trying to extract specific XML values from a database CLOB column.

Table : PDI_SUBMITTED_XML
(PSX_AGREEMENT  NUMBER(10),
 PSX_DOCUMENT   CLOB)

For example I'm trying to extract the value "Broker Region" from the BranchName tag below from the actual CLOB contents.

<?xml version="1.0" encoding="UTF-8"?>
<tns:AgreementWrapper xmlns:tns="http://ws.pancredit.com/wsdl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <tns:Agreement>
    <tns:AdminFee>199</tns:AdminFee>
    <tns:AdminFeeFinanced>true</tns:AdminFeeFinanced>
    <tns:Affordability>
      <tns:DownturnReason/>
    </tns:Affordability>
    <tns:AgreementNumber>13498443</tns:AgreementNumber>
    <tns:BankAccountAlreadyValidated>false</tns:BankAccountAlreadyValidated>
    <tns:BankAccountNumber>70872490</tns:BankAccountNumber>
    <tns:BankSortCode>404784</tns:BankSortCode>
    <tns:BranchName>Broker Region</tns:BranchName>
    <tns:BrandName>Rtl - VAT Assist Brand</tns:BrandName>

Up to now I've found no solution that will do this, someone has mentioned XMLPATH but see not many examples on internet that does it for the above example.

Does anybody have a solution to what seems simple enough to do but I've had no success up to now.

Upvotes: 0

Views: 261

Answers (2)

psaraj12
psaraj12

Reputation: 5072

Adding to Alex Poole's answer one more alternative.The DB fiddle here

    SELECT 
extractvalue(xmltype(PSX_DOCUMENT),'/AgreementWrapper/Agreement/BranchName',
    'xmlns="http://ws.pancredit.com/wsdl"') as Branch_name
    from PDI_SUBMITTED_XML;

For multiple values, you can use multiple extractvalues.The DB Fiddle here

    SELECT 
      extractvalue(
        xmltype(PSX_DOCUMENT), 
        '/AgreementWrapper/Agreement/BranchName', 
        'xmlns="http://ws.pancredit.com/wsdl"'
      ) as BRanch_name, 
      extractvalue(
        xmltype(PSX_DOCUMENT), 
        '/AgreementWrapper/Agreement/AgreementNumber', 
        'xmlns="http://ws.pancredit.com/wsdl"'
      ) as AgreementNumber 
    from 
      PDI_SUBMITTED_XML;

Upvotes: 0

Alex Poole
Alex Poole

Reputation: 191235

You can use XMLQuery to get a single value:

select xmlquery(
  'declare namespace tns="http://ws.pancredit.com/wsdl";
  /tns:AgreementWrapper/tns:Agreement/tns:BranchName/text()'
  passing xmltype(PSX_DOCUMENT)
  returning content
  ).getstringval() as branch_name
from PDI_SUBMITTED_XML
BRANCH_NAME
Broker Region

Or XMLTable if you need to get several things at once:

select x.agreement_number, x.branch_name
from PDI_SUBMITTED_XML
cross apply xmltable(
  xmlnamespaces('http://ws.pancredit.com/wsdl' as "tns"),
  '/tns:AgreementWrapper/tns:Agreement'
  passing xmltype(PSX_DOCUMENT)
  columns
    agreement_number number path 'tns:AgreementNumber',
    branch_name varchar2(30) path 'tns:BranchName'
) x
AGREEMENT_NUMBER BRANCH_NAME
13498443 Broker Region

In both cases the tns namespace has to be declared (unless you wildcard it).

db<>fiddle

Read more about those functions in the documentation.

Upvotes: 1

Related Questions