如何以管道分隔格式解析XML数据并插入表中

时间:2018-04-20 15:53:05

标签: oracle plsql xml-parsing xmltype extract-value

<Status>SUCCESS</Status>
<Count>7</Count>
<Data>
    <Content>S|123|03011990|5236158|19901254189684|</Content>
    <Content>S|456|02011991|2584959|19916584159385|</Content>
</Data>

我需要解析数据并插入表格。

INSERT INTO ins_data(TYPE,VNO,F_DATE,F_NO,F_CNO)。

我想在查询表时看到如下的输出。

S 123 03011990 5236158 19901254189684

S 456 02011991 2584959 19916584159385

1 个答案:

答案 0 :(得分:3)

此查询中有很多内容,所以我将逐步解释。这是完整的查询:

with D as
(select xmltype('<Root>
<Status>SUCCESS</Status>
<Count>7</Count>
<Data>
    <Content>S|123|03011990|5236158|19901254189684|</Content>
    <Content>S|456|02011991|2584959|19916584159385|</Content>
</Data>
</Root>') dataStr from dual)

select *
from(
    select id, trim(column_value) text,
           rank() over(partition by id order by rownum) pos
    from(
        select rownum id, extract(column_value, 'Content/text()') text
        from d,
        table(xmlsequence(extract(dataStr,'Root/Data/*'))) x
    ),
    xmltable(('"' || REPLACE(text, '|', '","') || '"'))
)pivot(
    max(text) for pos in (1 as TYPE, 2 as VNO, 3 as F_DATE, 4 as F_NO, 5 as F_CNO)
)

我的with子句使用xmltype命令将xml字符串转换为xml数据。

下一篇是这一篇:

select rownum id, extract(column_value, 'Content/text()') text
  from d,
  table(xmlsequence(extract(dataStr,'Root/Data/*'))) x

这使用xmlsequence命令从XML中的对象中提取行。我使用rownum为每一行分配一个ID。我稍后会需要这个领域。

下一部分是我从this site

中选取的一个漂亮的技巧
select id, trim(column_value) text,
           rank() over(partition by id order by rownum) pos
    from(
        select rownum id, extract(column_value, 'Content/text()') text
        from d,
        table(xmlsequence(extract(dataStr,'Root/Data/*'))) x
    ),
    xmltable(('"' || REPLACE(text, '|', '","') || '"'))

它使用XML表命令和REPLACE函数使用“|”的分隔符拆分每个值。我在值周围使用trim命令,以便将XML数据转换为字符串。我还使用等级窗口函数,以便在下一步中进行转向。

最后一部分是:

select *
from(
    select id, trim(column_value) text,
           rank() over(partition by id order by rownum) pos
    from(
        select rownum id, extract(column_value, 'Content/text()') text
        from d,
        table(xmlsequence(extract(dataStr,'Root/Data/*'))) x
    ),
    xmltable(('"' || REPLACE(text, '|', '","') || '"'))
)pivot(
    max(text) for pos in (1 as TYPE, 2 as VNO, 3 as F_DATE, 4 as F_NO, 5 as F_CNO)
)

我转向我在最后一步中制作的“pos”等级列,并为每个部分指定您指定的列名。

我的最终结果如下:

ID  TYPE    VNO     F_DATE      F_NO        F_CNO
1   S       123     03011990    5236158     19901254189684
2   S       456     02011991    2584959     19916584159385