Saya menghargai pertanyaan ini berumur beberapa tahun, tetapi saya datang ke sini dengan masalah yang sama dan yakin saya menemukan jawabannya.
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
);
Ini memberikan
catalog_id | category_id | product_id
---------------------------+-------------+------------
{manufacturer-catalog-id} | {category1} | {product1}
{manufacturer-catalog-id} | {category1} | {product2}
{manufacturer-catalog-id} | {category2} | {product3}
(3 rows)
Ini pada dasarnya melakukan pemilihan dasar yang mengembalikan dua kolom 1) xpath untuk mendapatkan daftar tugas (beberapa baris) dan 2) simpul kategori asli. Baris yang dikembalikan kemudian dikerjakan oleh pernyataan xpath tingkat yang lebih tinggi - id kategori dari kolom simpul kategori lengkap dan xpath tingkat kolom ke item daftar tugas.
Saya percaya masalah OP adalah bahwa mengemudi ini murni dari kolom daftar tugas tunggal berarti bahwa, karena postgres mengembalikan nodeset xml pada level yang sesuai, daripada menunjuk ke satu dom, output xml yang dikembalikan oleh ini berada di bawah level katalog dan bahwa xml ndoeset tidak dapat dilalui ke atas mis. dengan "leluhur::".
Semoga ini bisa membantu orang lain.
Sunting - Saya tidak dapat mengomentari kinerja ini, karena saya yakin xpath katalog-id akan diulang untuk setiap baris tugas dalam simpul katalog yang sama.