sql >> Databasteknik >  >> RDS >> PostgreSQL

Extrahera flera nivåer av xml-data med hjälp av xpath i postgres

Jag uppskattar att den här frågan är ett par år gammal, men jag kom hit med ett liknande problem och tror att jag hittade ett svar.

with x as (select
'<catalog catalog-id="manufacturer-catalog-id">
    <category-assignment category-id="category1" product-id="product1"/>
    <category-assignment category-id="category1" product-id="product2"/>
    <category-assignment category-id="category2" product-id="product3"/>
</catalog>'::xml as t
)
(
select 
       xpath('/catalog/@catalog-id', cat_node) catalog_id,
       xpath('/category-assignment/@category-id', cat_assn_list) category_id,
       xpath('/category-assignment/@product-id', cat_assn_list) product_id         
 from (select unnest(xpath('/catalog/category-assignment', t)) cat_assn_list, t cat_node from x) q
);

Detta ger

        catalog_id         | category_id | product_id
---------------------------+-------------+------------
 {manufacturer-catalog-id} | {category1} | {product1}
 {manufacturer-catalog-id} | {category1} | {product2}
 {manufacturer-catalog-id} | {category2} | {product3}
(3 rows)

Detta utför i princip basvalet som returnerar två kolumner 1) en xpath för att få tilldelningslista (flera rader) och 2) den ursprungliga kategorinoden. De returnerade raderna bearbetas sedan av xpath-satserna på högre nivå - kategori-id från den fullständiga kategorinodkolumnen och kolumnnivåns xpaths in i tilldelningslistan.

Jag tror att OP:s problem var att att driva bort detta rent av kolumnen för en enda tilldelningslista innebär att eftersom postgres returnerar xml-noduppsättningar på lämplig nivå, snarare än pekare till en enda dom, så är xml-utdata som returneras av detta under katalognivån och att xml ndoeset inte kan passeras uppåt t.ex. med "förfader::".

Hoppas detta hjälper någon annan.

Redigera - Jag kan inte kommentera prestandan för detta, eftersom jag tror att katalog-id xpath kommer att upprepas för varje tilldelningsrad inom samma katalognod.



  1. Hur skulle jag räkna MySQL(*) i Doctrine2?

  2. Bästa sättet med relationstabeller

  3. Villkorlig WHERE-sats i SQL Server

  4. Drivrutin:[email protected] returnerade null för URL... Under implementeringen av vårstart till Heroku