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

Posted

技术标签:

【中文标题】使用 SQL 或 PL/SQL 解析 XML 文档以提取字段值【英文标题】:Using SQL or PL/SQL to parse an XML document to extract field values 【发布时间】:2014-06-22 15:23:09 【问题描述】:

我有一个包含以下列的表格

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 的列表项是单个列中的逗号分隔值。在第二个示例中,列表项分别位于各自的列中。

【问题讨论】:

您遇到的格式问题是由文本中的硬制表符引起的。用空格替换制表符可以解决问题。分享和享受。 感谢您解决这个问题。 所以第二种结构并不“硬”,但如果作者的数量可以变化,它就没有意义。对于第一种格式,您需要我们分析函数(更具体地说 - 聚合。我建议您不要将此问题视为与 xml 相关,而是与“嵌套表”相关,这将使您更容易创建您想要的格式。将 xml 迁移到类似格式的嵌套表也很容易。如果您仍然遇到问题,请告诉我(现在要编写和模拟很多代码,我有点累,所以我明天会尽力提供更多帮助) 是的,我同意。第二个处理起来会更棘手。我将尝试和谷歌如何使用 xml 作为嵌套表。如果你能提供一个非常有用的例子。谢谢。 【参考方案1】:

我创建了一个名为 junk 的表,其中包含提到的列和数据,下面的选择似乎可以将数据作为逗号分隔的列表获取。不过不确定如何将它们放入单独的字段中。

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;

希望对你有帮助

【讨论】:

以上是关于使用 SQL 或 PL/SQL 解析 XML 文档以提取字段值的主要内容,如果未能解决你的问题,请参考以下文章

使用 PL/SQL 解析 XML 输出 html 中特定标签的内容

使用 pl/sql dom 解析器解析 XML 的最简单方法

如何在 PL/SQL 中解析 XML

Oracle PL/SQL 使用 XMLTABLE 解析 xml 中的嵌套对象

我正在尝试在 PL/SQL 中解析 XML。我无法从标签中检索属性值,我做错了啥?

在 PL/SQL 过程中解析具有名称空间的 XML 的未知数量节点?