2013-08-07 4 views
0

Мне нужно извлечь три столбца данных из столбца xml в postgres, чтобы xml был расширен в соответствующие столбцы. Один из этих столбцов должен быть атрибутом одного уровня вложенности xml, а остальные столбцы - атрибуты гнезда на один уровень вниз. Данные с более высокого уровня должны быть повторены. Это возможно? См. Пример ниже для чего-то конкретного.Извлечение нескольких уровней данных xml с использованием xpath в postgres

Спасибо, --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 - идентификатором категории из столбца узла полной категории и xpaths уровня столбца в элемент списка присваивания.

Я считаю, что проблема с OP заключалась в том, что управление этим чисто из одного столбца списка назначений означает, что, поскольку postgres возвращает xml-узлы на соответствующем уровне, а не указатели в единый dom, вывод xml, возвращаемый этим, ниже уровень каталога и что xml ndoeset не может быть пройден вверх, например, с «предком ::».

Надеюсь, что это поможет кому-то.

Редактировать - я не могу прокомментировать его выполнение, так как я считаю, что xpath каталога-id будет повторяться для каждой строки присваивания в одном и том же узле каталога.

Смежные вопросы