0

I am new to xml format and sql and I have an issue. I have a SQL query that returns the xml like the one below:

<?xml version="1.0" encoding="WINDOWS-1250"?>
<AROUND>
  <AB>
    <Connected>1</Connected>
    <EF>1010</EF>
    <GH>10162</GH>
    <IJ>HG-131120CXD</IJ>
    <KL>New</KL>
    <MN>284822</MN>
  </AB>
  <AB>
    <Connected>0</Connected>
    <EF>2123</EF>
    <GH>54321</GH>
    <IJ>HG-131120BRE</IJ>
    <KL>Old</KL>
    <MN>284822</MN>
  </AB>
  <AB>
    <Connected>1</Connected>
    <EF>4321</EF>
    <GH>12345</GH>
    <IJ>HG-131120DYX</IJ>
    <KL>New</KL>
    <MN>284822</MN>
  </AB>
</AROUND>

and I have to extract some of the values from it (for example: Connected, GH, IJ, KL) using a query so that every AB part of it, no matter how much of them are there (in this example there are 3, but there could be 1-10 or even more), has it's own row. For example (Connected, GH, IJ, KL), first row would be: 1 10162 HG-131120CXD New. And so on, and so on...Thanks in advance.

2
  • Do you really mean PL/SQL; or just Oracle-flavour SQL? PL/SQL is a a procedural extension. Commented Sep 8, 2021 at 9:57
  • 1
    SQL , my bad, I am a noob, sry for that Commented Sep 8, 2021 at 10:08

2 Answers 2

3

You can use XMLTable() to extract the data you want from your XML document; something like:

select x.connected, x.gh, x.ij, x.kl
from your_query q
cross apply xmltable (
  '/AROUND/AB'
  passing q.xml_doc
  columns
    connected number path 'Connected',
    gh number path 'GH',
    ij varchar2(20) path 'IJ',
    kl varchar2(10) path 'KL'
) x

where your_query is whatever query currently generates your XML document. If it generates a string value then you can wrap that in XMLType() to convert it.

db<>fiddle showing both, using a CTE to represent your existing query to produce an XML document or string value, to get:

CONNECTED |    GH | IJ           | KL 
--------: | ----: | :----------- | :--
        1 | 10162 | HG-131120CXD | New
        0 | 54321 | HG-131120BRE | Old
        1 | 12345 | HG-131120DYX | New

You can use that SQL statement within a PL/SQL block like any other SQL; if the XML document is in a variable you can do something like:

for r in (
  select x.connected, x.gh, x.ij, x.kl
  from xmltable (
    '/AROUND/AB'
    passing l_xml_doc -- local XMLType variable
    columns
      connected number path 'Connected',
      gh number path 'GH',
      ij varchar2(20) path 'IJ',
      kl varchar2(10) path 'KL'
  ) x
) loop
  -- do something with r.connected, r.gh etc.
end loop;

Sign up to request clarification or add additional context in comments.

Comments

0

You can use two XPath expressions with a Common Table Expressions. With the first you split the AB nodes and with the second you concatenate the relevant elements into a string.

with tmp as (
select unnest (xpath ('//AB',
'<?xml version="1.0" encoding="WINDOWS-1250"?>
<AROUND>
  <AB>
    <Connected>1</Connected>
    <EF>1010</EF>
    <GH>10162</GH>
    <IJ>HG-131120CXD</IJ>
    <KL>New</KL>
    <MN>284822</MN>
  </AB>
  <AB>
    <Connected>0</Connected>
    <EF>2123</EF>
    <GH>54321</GH>
    <IJ>HG-131120BRE</IJ>
    <KL>Old</KL>
    <MN>284822</MN>
  </AB>
  <AB>
    <Connected>1</Connected>
    <EF>4321</EF>
    <GH>12345</GH>
    <IJ>HG-131120DYX</IJ>
    <KL>New</KL>
    <MN>284822</MN>
  </AB>
</AROUND>')) ab
)
select unnest (xpath ('concat(//Connected/text()," ",//GH/text()," ",//IJ/text()," ",//KL/text())', tmp.ab)) ab
from tmp;

This returns:

            ab            
--------------------------
 1 10162 HG-131120CXD New
 0 54321 HG-131120BRE Old
 1 12345 HG-131120DYX New

2 Comments

The question is tagged for Oracle, not PostgreSQL, so this syntax won't work for the OP.
@AlexPoole Indeed I missed it.

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.