使用SQL或PL / SQL解析XML文档以提取字段值

时间:2014-06-22 15:23:09

标签: sql xml oracle xpath plsql

我有一个包含以下列的表

col1    varchar2
col2    varchar2
col3    varchar2
col4    clob
col5    varchar2
col6    varchar2
col7    varchar2
col8    varchar2

col4是一个CLOB类型字段,其中包含xml文档(注意:不是xmltype),格式如下

<document>
    <type>DocumentType</type>
    <authors>
        <author>Author1</author>
        <author>Author2</author>
        <author>Author3</author>
    </authors>
    <documentDate>01JAN2014</documentDate>
    <publishedCountries>
        <country>country1</country>
        <country>country2</country>
    </publishedCountries>
</document>

我想运行一个select语句来显示普通列和XML文档中的所有值。 我想知道如何编写一个可以在两个结构中输出的查询(即以下结构之一)

结构1

col1  col2  col3    col5  col6  col7  col8  type          authors                     documentDate  publishedCountries
xx    xx    xx      xx    xx    xx    xx    DocumentType  Author1, Author2, Author3   01JAN2014     country1,country2

结构2(即列表不以逗号分隔,但在各列中)

col1  col2  col3  col5  col6  col7  col8  type          author   author   author  documentDate  country   country
xx    xx    xx    xx    xx    xx    xx    DocumentType  Author1  Author2  Author3 01JAN2014     country1  country2

我一直在尝试第一个,这是我到目前为止的

select col1,    col2,   col3,   col5,   col6,   col7,   col8,
extract(xmltype(col4), '//type').getStringVal() type,
extract(xmltype(col4), '//authors').getStringVal() authors, 
extract(xmltype(col4), '//documentDate').getStringVal() documentDate, 
extract(xmltype(col4), '//publishedCountries').getStringVal() publishedCountries, 

上述查询确实有效,但仅限于以下

  • 列表不以逗号分隔
  • 标签仍然显示

我认为第二种结构稍微困难一些,因为我真的不知道如何将标记中的值插入到新列中。我想更喜欢这只是在上面的查询中只是SQL,但如果使用PL / SQL块更容易,那也没关系。

有什么想法吗?

提前致谢

修改

我努力在我提供的两个输出示例中对齐列值。基本上两者之间的区别在于,在第一个示例中,XML中的列表项是一列中的逗号分隔值。在第二个示例中,列表项各自位于各自的列中。

1 个答案:

答案 0 :(得分:1)

我创建了一个名为junk的表,其中包含上述列和数据,下面的select似乎可以将数据作为逗号分隔列表。不知道如何让他们进入单独的领域。

select j.col1, j.col2, j.col3, j.col5, j.col6, j.col7, j.col8, x.* from junk j, XMLTABLE ('$d' passing xmltype(col4) as "d" COLUMNS type varchar2(100) PATH '//type/text()', authors varchar2(100) PATH 'fn:string-join(//authors/author/text(), "; ")', documentDate varchar2(100) PATH '//documentDate/text()', publishedCountries varchar2(100) PATH 'fn:string-join(//publishedCountries/country/text(), "; ")') AS x;

希望这是有帮助的