Home > Net >  Postgres view via iterating with loop through xml
Postgres view via iterating with loop through xml

Time:10-24

First of all, I have following xml:

<?xml version="1.0" encoding="UTF-8"?>
   <control-sygnatura>XTW/GAT/GTW/1/00007</control-sygnatura>
   <control-inst>Firma 1</control-inst>
   <section-uczestnicy fr:section-status="changed">
      <section-uczestnicy-iteration>
         <section-uczestnik>
            <section-dane-uczestnika>
               <control-imie>Piotr</control-imie>
               <control-nazwisko>Pawel</control-nazwisko>
            </section-dane-uczestnika>
         </section-uczestnik>
      </section-uczestnicy-iteration>
      <section-uczestnicy-iteration>
         <section-uczestnik>
            <section-dane-uczestnika>
               <control-imie>Izabella</control-imie>
               <control-nazwisko>Agata</control-nazwisko>
            </section-dane-uczestnika>
         </section-uczestnik>
      </section-uczestnicy-iteration>
   </section-uczestnicy>
 </xml>

and I need to create view from this xml which contains 4 columns control-sygnatura, control-inst, control-imie and control-nazwisko.

I wrote following postgresql script:

CREATE OR REPLACE VIEW public.exportSL
 AS SELECT 
  btrim(xpath('//control-sygnatura/text()'::text, ofd.xml)::text, '{}'::text) AS control-sygnatura,
  btrim(xpath('//control-inst/text()'::text, ofd.xml)::text, '{}'::text)      AS control-inst,
  btrim(xpath('//control-imie/text()'::text, ofd.xml)::text, '{}'::text)      AS control-imie,
  btrim(xpath('//control-nazwisko/text()'::text, ofd.xml)::text, '{}'::text)  AS control-nazwisko,
 FROM orbeon_form_data ofd

But the problem is that my view have records

control-sygnatura      control-inst       control-imie     control-nazwisko
___________________________________________________________________________
XTW/GAT/GTW/1/00007    Firma 1            Piotr, Izabela   Pawel, Agata   
XTW/GAT/GTW/1/00007    Firma 1            Piotr, Izabela   Pawel, Agata   

instead of (one person from in one record )

control-sygnatura      control-inst       control-imie     control-nazwisko
___________________________________________________________________________
XTW/GAT/GTW/1/00007    Firma 1            Piotr            Pawel   
XTW/GAT/GTW/1/00007    Firma 1            Izabela          Agata   

Do You have any idea how to do it in postgres?

CodePudding user response:

Use XMLTABLE. Please note that your xml was invalid (missing root tag) and namespace fr: is not defined. I have added <xml> root tag and removed fr:. orbeon_form_data CTE with only one column is a mimic of your actual table.

with orbeon_form_data(xmlf) as 
(
 values 
 (
 '<?xml version="1.0" encoding="UTF-8"?>
  <xml>
  <control-sygnatura>XTW/GAT/GTW/1/00007</control-sygnatura>
  <control-inst>Firma 1</control-inst>
  <section-uczestnicy section-status="changed">
     <section-uczestnicy-iteration>
        <section-uczestnik>
           <section-dane-uczestnika>
              <control-imie>Piotr</control-imie>
              <control-nazwisko>Pawel</control-nazwisko>
           </section-dane-uczestnika>
        </section-uczestnik>
     </section-uczestnicy-iteration>
     <section-uczestnicy-iteration>
        <section-uczestnik>
           <section-dane-uczestnika>
              <control-imie>Izabella</control-imie>
              <control-nazwisko>Agata</control-nazwisko>
           </section-dane-uczestnika>
        </section-uczestnik>
     </section-uczestnicy-iteration>
   </section-uczestnicy>
  </xml>'::xml
 )
) 
select xmlt.* 
from orbeon_form_data 
cross join lateral
XMLTABLE
(
 '/xml/section-uczestnicy/section-uczestnicy-iteration/section-uczestnik/section-dane-uczestnika'
 PASSING by ref xmlf
 COLUMNS
  "control-sygnatura" text path '/xml/control-sygnatura',
  "control-inst" text path '/xml/control-inst',
  "control-imie" text PATH 'control-imie',
  "control-nazwisko" text PATH 'control-nazwisko'
) xmlt;
control-sygnatura control-inst control-imie control-nazwisko
XTW/GAT/GTW/1/00007 Firma 1 Piotr Pawel
XTW/GAT/GTW/1/00007 Firma 1 Izabella Agata
  • Related