Оценявам, че този въпрос е от преди няколко години, но дойдох тук с подобен проблем и вярвам, че намерих отговор.
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
);
Това дава
catalog_id | category_id | product_id
---------------------------+-------------+------------
{manufacturer-catalog-id} | {category1} | {product1}
{manufacturer-catalog-id} | {category1} | {product2}
{manufacturer-catalog-id} | {category2} | {product3}
(3 rows)
Това основно изпълнява базовия избор, който връща две колони 1) xpath за получаване на списък със задания (множество редове) и 2) оригиналния възел на категорията. Върнатите редове след това се обработват от операторите на xpath от по-високо ниво - идентификаторът на категорията от колоната с възел на пълната категория и xpaths на ниво колона в елемента от списъка с назначения.
Вярвам, че проблемът на OP беше, че извеждането на това изцяло извън колоната на списъка с единични назначения означава, че тъй като postgres връща xml nodesets на подходящото ниво, а не указатели в единичен dom, xml изходът, върнат от това, е под нивото на каталога и че xml ndoeset не може да бъде преминат нагоре, напр. с "предшественик::".
Надявам се това да помогне на някой друг.
Редактиране - не мога да коментирам ефективността на това, тъй като вярвам, че xpath на catalog-id ще се повтаря за всеки ред за присвояване в рамките на същия възел на каталога.