Oceňuji, že tato otázka je pár let stará, ale přišel jsem sem s podobným problémem a věřím, že jsem našel odpověď.
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
);
To dává
catalog_id | category_id | product_id
---------------------------+-------------+------------
{manufacturer-catalog-id} | {category1} | {product1}
{manufacturer-catalog-id} | {category1} | {product2}
{manufacturer-catalog-id} | {category2} | {product3}
(3 rows)
To v podstatě provádí základní výběr, který vrací dva sloupce 1) xpath k získání seznamu přiřazení (více řádků) a 2) původní uzel kategorie. Na vrácených řádcích se pak pracuje pomocí příkazů xpath vyšší úrovně - id kategorie ze sloupce úplného uzlu kategorie a xpath na úrovni sloupce do položky seznamu přiřazení.
Domnívám se, že problém OP spočíval v tom, že odstranění tohoto čistě z jediného sloupce seznamu přiřazení znamená, že protože postgres vrací xml nodesety na příslušné úrovni, spíše než ukazatele na jeden dom, výstup xml vrácený tímto je pod úrovní katalogu a že xml ndoeset nelze procházet směrem nahoru, např. s "předek::".
Doufám, že to někomu pomůže.
Upravit - Nemohu komentovat výkon tohoto, protože se domnívám, že xpath id katalogu se bude opakovat pro každý řádek přiřazení ve stejném uzlu katalogu.