Tôi cho rằng câu hỏi này đã cách đây vài năm, nhưng tôi đến đây với một vấn đề tương tự và tin rằng tôi đã tìm ra câu trả lời.
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
);
Điều này mang lại cho
catalog_id | category_id | product_id
---------------------------+-------------+------------
{manufacturer-catalog-id} | {category1} | {product1}
{manufacturer-catalog-id} | {category1} | {product2}
{manufacturer-catalog-id} | {category2} | {product3}
(3 rows)
Điều này về cơ bản thực hiện lựa chọn cơ sở trả về hai cột 1) một xpath để nhận danh sách gán (nhiều hàng) và 2) nút danh mục ban đầu. Sau đó, các hàng trả về sẽ được xử lý bởi các câu lệnh xpath cấp cao hơn - id danh mục từ cột nút danh mục đầy đủ và xpath cấp cột vào mục danh sách gán.
Tôi tin rằng vấn đề của OP là việc loại bỏ điều này hoàn toàn khỏi cột danh sách chuyển nhượng đơn lẻ có nghĩa là, vì postgres đang trả về các tập nút xml ở mức thích hợp, thay vì con trỏ vào một dom duy nhất, đầu ra xml được trả về bởi điều này thấp hơn mức danh mục và rằng ndoeset xml không thể được chuyển lên trên, ví dụ:với "tổ tiên ::".
Hy vọng điều này sẽ giúp ích cho ai đó.
Chỉnh sửa - Tôi không thể nhận xét về hiệu suất của điều này, vì tôi tin rằng xpath catalog-id sẽ được lặp lại cho mọi hàng gán trong cùng một nút danh mục.