1

我需要从 postgres 中的 xml 列中提取三列数据,以便将 xml 扩展为适当的列。这些列中的一列需要是 xml 的一个嵌套级别的属性,而其他列是下一层嵌套的属性。应重复来自更高级别的数据。这可能吗?有关具体内容,请参见下面的示例。

谢谢,--sw

考虑以下查询:

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', catalog_xml) catalog_id,  
    xpath('//@category-id', catalog_xml) category_assignment_category_id,
    xpath('//@product-id', catalog_xml) category_assignment_product_id
from (select unnest(xpath('/catalog', t)) catalog_xml from x) q
) 

此查询返回以下数据:

"{manufacturer-catalog-id}";"{category1,category1,category2}";"{product1,product2,product3}"

这个查询:

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', catalog_xml) catalog_id,  
    xpath('//@category-id', catalog_xml) category_assignment_category_id,
    xpath('//@product-id', catalog_xml) category_assignment_product_id
from (select unnest(xpath('/catalog/category-assignment', t)) catalog_xml from x) q
) 

---已编辑---

返回此数据:

"{}";"{category1}";"{product1}"
"{}";"{category1}";"{product2}"
"{}";"{category2}";"{product3}"

我需要这些数据:

"{manufacturer-catalog-id}";"{category1}";"{product1}"
"{manufacturer-catalog-id}";"{category1}";"{product2}"
"{manufacturer-catalog-id}";"{category2}";"{product3}"
4

2 回答 2

4

我觉得这个问题已经有几年了,但我带着类似的问题来到这里,相信我找到了答案。

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 语句处理 - 来自完整类别节点列的类别 ID 和列级别 xpath 到分配列表项中。

我相信 OP 的问题是,纯粹从单个分配列表列中驱动它意味着,由于 postgres 在适当的级别返回 xml 节点集,而不是指向单个 dom 的指针,因此返回的 xml 输出低于目录级别和xml ndoeset 不能向上遍历,例如使用“ancestor::”。

希望这对其他人有帮助。

编辑-我无法评论此性能,因为我相信同一目录节点中的每个分配行都会重复目录 ID xpath。

于 2015-04-23T14:55:07.850 回答
-1

我认为您将不得不分多个阶段进行。这是我所得到的。然后,您可以在此处提取元素并将它们绑定回父级:

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
), segs_raw as (select unnest(xpath('/catalog', t)) catalog_xml from x),
segs as (select catalog_xml, unnest(xpath('/catalog/@catalog-id', catalog_xml)) catalog_id from segs_raw)
select * from segs;

为了协调事情,我认为下一步是将类别分配 XML 与目录 ID 一起提取,然后将它们提取出来,这样您就可以完成一半了。在提取级别,您必须保留要制表的数据,否则您将获得隐式交叉连接。

于 2013-11-11T02:57:38.403 回答