Читать атрибуты XML в postgres - PullRequest
1 голос
/ 27 марта 2019

Я использую первый таймер XML в Postgres и сталкиваюсь с проблемой.У меня ниже xml в переменной с именем XMLCONTENT

<?xml version="1.0" encoding="UTF-8"?>
<Actions>
   <Action ActionID="90e0dbef-c23a-4fcd-bfa8-75d8bfa2c9e2" />
   <Action ActionID="6a1998e1-70f1-4611-992a-7a27e2834c35" />
   <Action ActionID="43dd9a91-c6d3-4980-b211-9b3780f04305" />
   <Action ActionID="cdf01821-ac28-45a9-abf8-a7d7c9426518" />
   <Action ActionID="e86fac8a-84e3-41ba-8bee-c7ffd1ac8ee5" />
   <Action ActionID="a68dd878-ba1e-4fd9-b436-cdc15eccffb6" />
   <Action ActionID="cd863a5a-83e9-489e-b24d-ff6638c5b190" />
   <Action ActionID="720ba9c7-b797-4b2e-913e-11ac3ecd7b7f" />
   <Action ActionID="b6b35d0d-938e-45d3-96d1-0c8ca3ad59f3" MessageID="42f40c3a-4426-4506-86c5-222fb03c2114" />
</Actions>

Я хочу извлечь детали из этого XML, и я использую запрос ниже

Select  
    Unnest(xpath('//@ActionID',XMLCONTENT)) as ID,
    Unnest(xpath('//@MessageID',XMLCONTENT)) as MessageID,
    Unnest(xpath('//@Operator',XMLCONTENT)) as Operator

, но я получаю неправильный вывод, как показано ниже

enter image description here

MessageID связан с неверным actionID.Как правильно пройти этот XML?

1 Ответ

2 голосов
/ 27 марта 2019

Причиной того, что ваш запрос не работает, является использование unnest() в списке выбора: каждый вызов unnest() добавляет новую строку к результату.

Вам необходимо использовать unnest в предложении from, чтобы создать по одной строке для каждого <Action> элемента:

with data (xmlcontent) as (
  values ('
  <Actions>
     <Action ActionID="90e0dbef-c23a-4fcd-bfa8-75d8bfa2c9e2" />
     <Action ActionID="6a1998e1-70f1-4611-992a-7a27e2834c35" />
     <Action ActionID="43dd9a91-c6d3-4980-b211-9b3780f04305" />
     <Action ActionID="cdf01821-ac28-45a9-abf8-a7d7c9426518" />
     <Action ActionID="e86fac8a-84e3-41ba-8bee-c7ffd1ac8ee5" />
     <Action ActionID="a68dd878-ba1e-4fd9-b436-cdc15eccffb6" />
     <Action ActionID="cd863a5a-83e9-489e-b24d-ff6638c5b190" />
     <Action ActionID="720ba9c7-b797-4b2e-913e-11ac3ecd7b7f" />
     <Action ActionID="b6b35d0d-938e-45d3-96d1-0c8ca3ad59f3" 
             MessageID="42f40c3a-4426-4506-86c5-222fb03c2114" />
  </Actions>'::xml)
)
select (xpath('//@ActionID', xt.action))[1] as id, 
       (xpath('//@MessageID', xt.action))[1] as message_id
from data
  cross join unnest(xpath('/Actions/Action', xmlcontent)) as xt(action);

Возвращает:

id                                   | message_id                          
-------------------------------------+-------------------------------------
90e0dbef-c23a-4fcd-bfa8-75d8bfa2c9e2 |                                     
6a1998e1-70f1-4611-992a-7a27e2834c35 |                                     
43dd9a91-c6d3-4980-b211-9b3780f04305 |                                     
cdf01821-ac28-45a9-abf8-a7d7c9426518 |                                     
e86fac8a-84e3-41ba-8bee-c7ffd1ac8ee5 |                                     
a68dd878-ba1e-4fd9-b436-cdc15eccffb6 |                                     
cd863a5a-83e9-489e-b24d-ff6638c5b190 |                                     
720ba9c7-b797-4b2e-913e-11ac3ecd7b7f |                                     
b6b35d0d-938e-45d3-96d1-0c8ca3ad59f3 | 42f40c3a-4426-4506-86c5-222fb03c2114

Всписок выбора, вы знаете, что каждый '//@ActionID' возвращает только один элемент, поэтому больше нет необходимости использовать unnest на этом уровне.

Онлайн пример: https://rextester.com/MWBCEN37238


Если бы вы использовали Postgres 10 или более позднюю версию, это было бы немного проще с XMLTABLE :

select xt.*
from data 
     cross join xmltable ('/Actions/Action'
               passing xmlcontent
               columns id         uuid path '@ActionID', 
                       message_id uuid path '@MessageID'
              ) as xt;

Онлайн пример: https://dbfiddle.uk/?rdbms=postgres_10&fiddle=1e70be54c25a42db5ebff9a996423920


Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...