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

Posted

技术标签:

【中文标题】在 PL/SQL 过程中解析具有名称空间的 XML 的未知数量节点?【英文标题】:Parsing unknown number nodes of a XML with namespace in PL/SQL procedure? 【发布时间】:2015-04-01 09:22:22 【问题描述】:

我有一个 xml_data 我正在传递给程序-

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:a xmlns:ns2="http://www.sbc.com/iag/schemas/adapters" xmlns="http://www.sbc.com/iag/schemas/core">
     <ns2:b>

        <ns2:OrderNumber>99995</ns2:OrderNumber>
        <ns2:ServiceOrderNumber>88888</ns2:ServiceOrderNumber>

    </ns2:b>
    <ns2:b>

        <ns2:OrderNumber>99699</ns2:OrderNumber>
        <ns2:ServiceOrderNumber>88888</ns2:ServiceOrderNumber>

    </ns2:b>
    <ns2:b>

        <ns2:OrderNumber>69999</ns2:OrderNumber>
        <ns2:ServiceOrderNumber>88888</ns2:ServiceOrderNumber>

    </ns2:b
    <ns2:b>

        <ns2:OrderNumber>67999</ns2:OrderNumber>
        <ns2:ServiceOrderNumber>88888</ns2:ServiceOrderNumber>

    </ns2:b>
</ns2:a>

节点

ns2:b

可以重复任意次数并且不是固定的。 我如何获取这个

ns2:订单号

从 oracle 程序中的这个 xml 数据。如果

ns2:b(ns2:OrderNumber)

通过下面的代码只发生一次-

select extractValue(
  xml_data, 
   xmlns="http://www.sbc.com/iag/schemas/core"'
)   '/ns2:a/ns2:b/ns2:OrderNumber/text()',
  'xmlns:ns2="http://www.sbc.com/iag/schemas/adapters",
into order_number from dual;

  dbms_output.put_line('FailedRetry -' ||order_number);

但是我如何继续迭代直到我得到那个节点的所有值

在 XML 中。我尝试了在此站点上发布的不同解决方案,但没有一个有效。

【问题讨论】:

【参考方案1】:

使用XMLTABLE。

select y.* 
from dual,
xmltable( xmlnamespaces(default 'http://www.sbc.com/iag/schemas/core', 'http://www.sbc.com/iag/schemas/adapters' as "ns2"), 'ns2:a/ns2:b'
passing xml_data
columns OrderNumber varchar2(10) path 'ns2:OrderNumber',
    ServiceOrderNumber varchar2(10) path 'ns2:ServiceOrderNumber'
) y;

示例查询:

SQL> with x(xml_data) as (
        select xmltype('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:a xmlns:ns2="http://www.sbc.com/iag/schemas/adapters" xmlns="http://www.sbc.com/iag/schemas/core">
     <ns2:b>
        <ns2:OrderNumber>99995</ns2:OrderNumber>
        <ns2:ServiceOrderNumber>88888</ns2:ServiceOrderNumber>
    </ns2:b>
    <ns2:b>
        <ns2:OrderNumber>99699</ns2:OrderNumber>
        <ns2:ServiceOrderNumber>88888</ns2:ServiceOrderNumber>
    </ns2:b>
    <ns2:b>
        <ns2:OrderNumber>69999</ns2:OrderNumber>
        <ns2:ServiceOrderNumber>88888</ns2:ServiceOrderNumber>
    </ns2:b>
    <ns2:b>
        <ns2:OrderNumber>67999</ns2:OrderNumber>
        <ns2:ServiceOrderNumber>88888</ns2:ServiceOrderNumber>
    </ns2:b>
</ns2:a>')
from dual
)
select y.* 
from x,
xmltable( xmlnamespaces(default 'http://www.sbc.com/iag/schemas/core', 'http://www.sbc.com/iag/schemas/adapters' as "ns2"), 'ns2:a/ns2:b'
passing xml_data
columns OrderNumber varchar2(10) path 'ns2:OrderNumber',
        ServiceOrderNumber varchar2(10) path 'ns2:ServiceOrderNumber'
) y;

ORDERNUMBE SERVICEORD
---------- ----------
99995      88888
99699      88888
69999      88888
67999      88888

Elapsed: 00:00:00.03
SQL> 

如果要迭代每条记录,请在游标中使用它。

decare
    cursor c1 is select y.* 
    from dual,
    xmltable( xmlnamespaces(default 'http://www.sbc.com/iag/schemas/core', 'http://www.sbc.com/iag/schemas/adapters' as "ns2"), 'ns2:a/ns2:b'
    passing xml_data
    columns OrderNumber varchar2(10) path 'ns2:OrderNumber',
        ServiceOrderNumber varchar2(10) path 'ns2:ServiceOrderNumber'
    ) y;
begin
    for i in c1
    loop
        dbms_output.put_line('FailedRetry -' ||i.OrderNumber || ' '|| i.ServiceOrderNumber);
    end loop;
end;

【讨论】:

非常感谢 Eat,但是当我尝试编译它时显示的错误-Error(14,2): PLS-00428: an INTO 子句应该在这个 SELECT 语句中,即在 x (xml_data) 作为行。 如果你在plsql中使用它,你应该在游标中使用它。 但是 oracle 也支持 'with',是吗?如果您能告诉我如何在此处使用光标,那将非常有帮助。

以上是关于在 PL/SQL 过程中解析具有名称空间的 XML 的未知数量节点?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PL/SQL 中解析 XML

在 PL/SQL 中解析 XML 或 JSON

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

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

从 xml 中提取值,它具有命名空间并解析 xml cdata

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