sql >> Base de Datos >  >> RDS >> PostgreSQL

Extracción de múltiples niveles de datos xml usando xpath en postgres

Creo que esta pregunta tiene un par de años, pero vine aquí con un problema similar y creo que encontré una respuesta.

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
);

Esto da

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

Básicamente, esto realiza la selección base que devuelve dos columnas 1) un xpath para obtener la lista de asignaciones (varias filas) y 2) el nodo de categoría original. Luego, las filas devueltas son procesadas por las declaraciones xpath de nivel superior:el ID de categoría de la columna de nodo de categoría completa y los xpaths de nivel de columna en el elemento de la lista de asignación.

Creo que el problema del OP fue que sacar esto puramente de la columna de la lista de asignación única significa que, dado que Postgres está devolviendo conjuntos de nodos xml en el nivel apropiado, en lugar de punteros en un solo dom, la salida xml devuelta por esto está por debajo del nivel del catálogo y que xml ndoeset no se puede atravesar hacia arriba, p. con "antepasado::".

Espero que esto ayude a alguien más.

Editar:no puedo comentar sobre el rendimiento de esto, ya que creo que el xpath de id de catálogo se repetirá para cada fila de asignación dentro del mismo nodo de catálogo.