JSONb'yi tag_name ve tag_value ile XML'e postala

Oct 11 2020

Postgres XML işlevlerinde yeniyim. Aşağıdaki gibi bir masam var:

id  (VARCHAR) | field1 (text) | attributes  (jsonb)     
--------------+---------------+----------------------------------

 123          |   a           |   {"age": "1", "place": "TX"}                 
 456          |   b           |   {"age": "2", "name": "abcdef"}     
 789          |               |       
 098          |   c           |   {"name": "gefd"}     

Bunu şuna dönüştürmek istiyor:

 <Company id="123" field="a">
      <CompanyTag tagName="age" tagValue="1"/>
      <CompanyTag tagName="place" tagValue="TX"/>
 </Company>
 <Company id="456" field="b">
      <CompanyTag tagName="age" tagValue="2"/>
      <CompanyTag tagName="name" tagValue="abcdef"/>
 </Company>
 <Company id="789"/>
  <Company id="098" field="c">
      <CompanyTag tagName="name" tagValue="gefd"/>
 </Company>

Aşağıdaki kullanarak ilk iki sütunu kolayca dönüştürebildi, ancak JSONb en zor bölüme sahip:

#SELECT xmlelement(name Company, xmlattributes(id as id, field1 as field)) from comp_emp;;
 <Company id="123" field="a"/>
 <Company id="456" field="b"/>
 <Company id="789"/>
 <Company id="098" field="c"/>

Lütfen beni doğru yönde yönlendirin.

Yanıtlar

2 Bergi Oct 11 2020 at 06:09

@Georges Martin'in çözümüne dayanarak, bir yanal birleştirme ve bir gruplama cümlesi kullanmam, sadece iç içe geçmiş bir alt sorgu kullanıyorum:

SELECT XMLELEMENT(
  NAME "Company", 
  XMLATTRIBUTES(id AS id, field1 AS field), 
  (SELECT XMLAGG(
    XMLELEMENT(
      NAME "companyTag", 
      XMLATTRIBUTES(
        attr.key AS "tagName", 
        attr.value AS "tagValue"
      )
    )
  ) FROM JSONB_EACH_TEXT(attributes) AS attr)
) FROM comp_emp;

( çevrimiçi demo )

1 GeorgesMartin Oct 11 2020 at 05:53

Bu, field1sütunu unuttuğum için kısmi bir çözüm ama bu:

SELECT 
 XMLELEMENT(
  NAME "Company", 
  XMLATTRIBUTES(id AS id), 
  XMLAGG(
   XMLELEMENT(
    NAME "CompanyTag", 
    XMLATTRIBUTES(
     (attr).key AS "tagName", 
     (attr).value AS "tagValue"
    )
   )
  )
 ) 
FROM (
 SELECT 
  id, JSONB_EACH_TEXT(attributes) AS attr 
 FROM comp_emp
) AS sub 
GROUP BY id;

zaten geri dönüyor:

<Company id="098">
  <CompanyTag tagName="name" tagValue="gefd"/>
</Company>
<Company id="456">
  <CompanyTag tagName="age" tagValue="2"/>
  <CompanyTag tagName="name" tagValue="abcdef"/>
</Company>
<Company id="123">
  <CompanyTag tagName="age" tagValue="1"/>
  <CompanyTag tagName="place" tagValue="TX"/>
</Company>