2016-10-24 2 views
0

Я получил такое XML:Родитель XML в SQL запросе XPath

< person code="SNIPER"> 

    <type code="SINGLE" /> 

<version code="1" dateFrom="2015-03-20" /> 
</version> 

<version code="2" dateFrom="2012-06-15" /> 
</version> 

< /person> 

У меня есть SQL-запрос:

select extract(VALUE(cd_xml), 'version/@code').getstringval() code 
     ,cast(to_timestamp_tz(replace(extract(VALUE(cd_xml), 'version/@dateFrom') 
                .getstringval(), 'T', ''), 
              'yyyy-mm-dd') as date) datefrom 

from table(xmlsequence(extract(get_xml, '/*/person/version'))) cd_xml 

Это возвращает меня две строки:

1 2015-03-10 

2 2012-06-15 

Я хотел бы для получения в результате таких строк:

single 1 2015-03-10 

single 2 2012-06-15 

или

sniper 1 2015-03-10 

sniper 2 2012-06-15 

Как это сделать ?? Я пробовал разные thigs с родительским пунктом, но я нету сделал это :(

+0

Как вы решите, хотите ли вы «сингл» или «снайпер»? Кроме того, в вашем XML есть узлы 'version', которые являются самозакрывающимися и с явными тегами закрытия, что делает его недействительным; и ваш XPath ожидает узла * выше * 'person'. Можете ли вы отредактировать вопрос, чтобы сделать его последовательным? –

+0

Упрощенная проблема. Я получил xml, где мало таких xmls. Дело в том, что мне нужны строки с «синглом». Но в случае, если я каким-то образом получаю строки со снайпером, я могу сделать еще один запрос на подключение «снайпера» к «одиночному», – MPAW

ответ

0

The extract function is deprecated, вы можете использовать его для этого, но это лучше использовать XMLQuery/XMLTable, например, при условии, get_xml это функция, которая возвращает ваш правильно отформатированный XML, как XMLType:

select * 
from xmltable('/persons/person/version' 
    passing get_xml 
    columns person_code varchar2(10) path './../@code', 
    type_code varchar2(10) path './../type/@code', 
    version_code number path '@code', 
    version_datefrom date path '@dateFrom' 
); 

Demo со статическим XML, изменен от того, что вы вывесили в соответствии с шаблоном вы использовали:

select * 
from xmltable('/persons/person/version' 
    passing xmltype('<persons> 
    <person code="SNIPER"> 
    <type code="SINGLE" /> 
    <version code="1" dateFrom="2015-03-20" /> 
    <version code="2" dateFrom="2012-06-15" /> 
    </person> 
</persons>') 
    columns person_code varchar2(10) path './../@code', 
    type_code varchar2(10) path './../type/@code', 
    version_code number path '@code', 
    version_datefrom date path '@dateFrom' 
); 

PERSON_COD TYPE_CODE VERSION_CODE VERSION_DA 
---------- ---------- ------------ ---------- 
SNIPER  SINGLE    1 2015-03-20 
SNIPER  SINGLE    2 2012-06-15 

Ваша манипуляция предлагает dateFrom действительно полная метка времени, больше похожа на '2015-03-20T12:34:56+04:00'; если вы просто хотите даты часть того, что вы можете получить, что более просто слишком, извлекая столбец как timestamp with time zone, а затем литье в конце:

select person_code, type_code, version_code, 
    cast(version_datefrom as date) as version_datefrom 
from xmltable('/persons/person/version' 
    passing xmltype('<persons> 
    <person code="SNIPER"> 
    <type code="SINGLE" /> 
    <version code="1" dateFrom="2015-03-20T12:34:56+04:00" /> 
    <version code="2" dateFrom="2012-06-15T23:00:00+00:00" /> 
    </person> 
</persons>') 
    columns person_code varchar2(10) path './../@code', 
    type_code varchar2(10) path './../type/@code', 
    version_code number path '@code', 
    version_datefrom timestamp with time zone path '@dateFrom' 
); 
Смежные вопросы