PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Extraction de plusieurs niveaux de données xml à l'aide de xpath dans postgres

J'apprécie que cette question date de quelques années, mais je suis venu ici avec un problème similaire et je pense avoir trouvé une réponse.

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

Cela donne

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

Cela exécute essentiellement la sélection de base qui renvoie deux colonnes 1) le xpath pour obtenir la liste d'affectation (plusieurs lignes) et 2) le nœud de catégorie d'origine. Les lignes renvoyées sont ensuite traitées par les instructions xpath de niveau supérieur - l'identifiant de catégorie de la colonne de nœud de catégorie complète et les xpaths de niveau colonne dans l'élément de liste d'affectation.

Je crois que le problème de l'OP était que le fait de conduire cela uniquement à partir de la colonne de liste d'affectation unique signifie que, puisque postgres renvoie des ensembles de nœuds xml au niveau approprié, plutôt que des pointeurs dans un seul dom, la sortie xml renvoyée par ceci est inférieure au niveau du catalogue et que xml ndoeset ne peut pas être parcouru vers le haut, par ex. avec "ancêtre ::".

J'espère que cela aidera quelqu'un d'autre.

Modifier - Je ne peux pas commenter les performances de cela, car je pense que le xpath catalog-id sera répété pour chaque ligne d'affectation dans le même nœud de catalogue.