在postgres中使用xpath提取多级xml数据

在postgres中使用xpath提取多级xml数据,xml,postgresql,xpath,Xml,Postgresql,Xpath,我需要从postgres中的xml列中提取三列数据,以便将xml扩展为相应的列。其中一列需要是xml的一个嵌套级别的属性,而其他列则是向下一个嵌套级别的属性。应重复较高级别的数据。这可能吗?具体内容请参见下面的示例 谢谢,-sw 考虑以下查询: with x as (select '<catalog catalog-id="manufacturer-catalog-id"> <category-assignment category-id="category1" pro

我需要从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
) 
此查询:

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
) 
我需要这些数据:

"{manufacturer-catalog-id}";"{category1,category1,category2}";"{product1,product2,product3}"
"{}";"{category1}";"{product1}"
"{}";"{category1}";"{product2}"
"{}";"{category2}";"{product3}"
"{manufacturer-catalog-id}";"{category1}";"{product1}"
"{manufacturer-catalog-id}";"{category1}";"{product2}"
"{manufacturer-catalog-id}";"{category2}";"{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
), 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一起取出,然后取出这些内容,这样就可以完成一半。在leach级别,您必须保留要制表的数据,因为否则您将得到隐式交叉联接。

我认为您必须分多个阶段进行。这是我能到的最远的地方。然后,您可以在此处提取元素并将其绑定回父元素:

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一起取出,然后取出这些内容,这样就可以完成一半。在leach级别,您必须保留要制表的数据,否则您将得到隐式交叉联接。

我觉得这个问题已经有好几年了,但我来到这里时遇到了一个类似的问题,我相信我找到了答案

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
);
这基本上执行基本选择,返回两列:1是xpath以获取多行分配列表,2是原始类别节点。然后,返回的行由更高级别的xpath语句处理—类别id从完整类别节点列开始,列级别xpath进入分配列表项

我认为OP的问题在于,将其完全从单一赋值列表列中删除意味着,由于postgres返回的是适当级别的xml节点集,而不是指向单个dom的指针,因此它返回的xml输出低于目录级别,并且xml节点集不能向上遍历,例如使用祖先::

希望这对其他人有帮助


编辑-我不能评论这个问题的性能,因为我相信目录id xpath将在同一目录节点内的每个分配行中重复出现。

我觉得这个问题已经有好几年了,但我来到这里时遇到了一个类似的问题,我相信我找到了答案

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
);
这基本上执行基本选择,返回两列:1是xpath以获取多行分配列表,2是原始类别节点。然后,返回的行由更高级别的xpath语句处理—类别id从完整类别节点列开始,列级别xpath进入分配列表项

我认为OP的问题在于,将其完全从单一赋值列表列中删除意味着,由于postgres返回的是适当级别的xml节点集,而不是指向单个dom的指针,因此它返回的xml输出低于目录级别,并且xml节点集不能向上遍历,例如使用祖先::

希望这对其他人有帮助


编辑-我不能对其性能发表评论,因为我相信目录id xpath将对同一目录节点内的每个分配行重复。

如果不需要任何结果,则不需要发送查询。我猜你忘了在你的问题中包括什么嗯,对不起。我修正了。如果你不需要任何结果,你不需要发送查询。我猜你忘了在你的问题中包括什么嗯,对不起。我修好了。