2013-08-07 81 views
0

我需要從postgres中的xml列提取三列數據,以便將xml擴展到適當的列中。其中一個列需要是xml的一個嵌套級別的屬性,其他列是向下一級的嵌套的屬性。應該重複更高一級的數據。這可能嗎?有關具體內容,請參閱下面的示例。在postgres中使用xpath提取多個級別的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 
) 

- -EDITED ---

返回此數據:

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

我需要這樣的數據:

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

如果您不需要任何結果,則不需要發送查詢。我想你忘了在你的問題中包含一些東西? :) –

+0

嗯,對不起。我修好了它。 –

回答

-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一起,然後扯這些了,所以這會讓你在中途停下來。在浸出級別,您必須保留要列表的數據,否則您將得到隱式交叉連接。

3

我說這個問題已經有幾年了,但是我帶着一個類似的問題來到這裏,相信我找到了答案。

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語句處理 - 來自完整分類節點列的分類標識以及列級xpath到分配列表項中。

我相信OP的問題在於,將此純粹從單個賦值列表中移除意味着,因爲postgres正在返回適當級別的xml節點集,而不是指向單個dom的指針,所以返回的xml輸出低於目錄級別和xml ndoeset不能被向上遍歷,例如與「祖先::」。

希望這可以幫助別人。

編輯 - 我不能評論這一點,因爲我相信catalog-id xpath將在同一個目錄節點中的每個賦值行上重複。