PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Extraindo vários níveis de dados xml usando xpath no postgres


Aprecio que esta pergunta tenha alguns anos, mas vim aqui com um problema semelhante e acredito que encontrei uma resposta.
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
);

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

Isso basicamente executa a seleção de base que retorna duas colunas 1) um xpath para obter a lista de atribuição (várias linhas) e 2) o nó de categoria original. As linhas retornadas são então trabalhadas pelas instruções xpath de nível superior - o category-id da coluna do nó de categoria completo e os xpaths de nível de coluna para o item da lista de atribuição.

Acredito que o problema do OP foi que direcionar isso puramente para fora da coluna da lista de atribuição única significa que, como o postgres está retornando conjuntos de nós xml no nível apropriado, em vez de ponteiros para um único dom, a saída xml retornada por isso está abaixo do nível do catálogo e esse xml ndoeset não pode ser percorrido para cima, por exemplo. com "ancestral::".

Espero que isso ajude alguém.

Editar - não posso comentar sobre o desempenho disso, pois acredito que o xpath do catalog-id será repetido para cada linha de atribuição no mesmo nó do catálogo.