使用xpath在XMLType列中查找xml中特定节点的出现,并为root和chaild节点标记指定不同的名称空间前缀

时间:2017-01-29 21:36:05

标签: oracle xpath namespaces

我必须在XML中找到存在于特定查询中的Oracle数据库列(CLOB数据类型)中的特定节点。

我想过使用Oracle函数EXISTSNODE来获得预期的结果。问题是必须检查其出现/存在的根节点和子节点的名称空间具有不同的名称空间。

例如,XML如下所示:

<workcontract:workcontract 
     xmlns:workcontract ="http://schema.abc.nl/cdm/inc/v1" 
     xmlns:ns2="http://schema.abc.nl/cdm/ins/v1">
    <raamwerkcontract:verzekeringnemer>
        <workcontract:werkgever>
            <ns2:rekening>
                <ns2:rekeningnummer>123456789</ns2:rekeningnummer>
            </ns2:rekening>
        </workcontract:werkgever>
    </raamwerkcontract:verzekeringnemer>
</workcontract:workcontract>

我必须找到XML是否包含/workcontract/verzekeringnemer/rekening的节点。

EXISTSNODE的签名如下所示:

EXISTSNODE(XMLType_instance, XPath_string, namespace_string)

Namespace_string参数是可选的。

使用多个namespace_string,我如何使用EXISTSNODE函数?

我的SELECT查询适用于节点werkgever,如下所示:

SELECT offerteId 
FROM QUOTATIONS 
WHERE EXISTSNODE(XMLTYPE(XMLOfferte), ’//workcontract:workcontract/raamwerkcontract:verzekeringnemer/ workcontract:werkgever’, ‘xmlns:workcontract ="http://schema.abc.nl/cdm/inc/v1"’) = 1;

注意:XMLOfferte列的类型为CLOB

如何编写查询以查找具有不同命名空间的节点rekening的出现,即xmlns:ns2=”http://schema.abc.nl/cdm/ins/v1”

除了使用EXISTSNODE函数之外还有其他方法吗?

请帮忙。

此致 Aniket

1 个答案:

答案 0 :(得分:1)

文档中没有明确规定,但您可以在existsnode()命名空间参数中提供多个命名空间,可选择以逗号分隔;将raamwerkcontract添加到您的XML和命名空间参数中(尽管您在发布问题时可能没有一致地重命名):

SELECT offerteId 
FROM QUOTATIONS 
WHERE EXISTSNODE(XMLTYPE(XMLOfferte),
  '//workcontract:workcontract/raamwerkcontract:verzekeringnemer/workcontract:werkgever',
  'xmlns:workcontract="http://schema.abc.nl/cdm/inc/v1" xmlns:raamwerkcontract="http://schema.abc.nl/cdm/inc/v1"') = 1;

 OFFERTEID
----------
        42

使用ns2的第三个命名空间:

SELECT offerteId 
FROM QUOTATIONS 
WHERE EXISTSNODE(XMLTYPE(XMLOfferte),
  '//workcontract:workcontract/raamwerkcontract:verzekeringnemer/workcontract:werkgever/ns2:rekening',
  'xmlns:workcontract="http://schema.abc.nl/cdm/inc/v1" xmlns:raamwerkcontract="http://schema.abc.nl/cdm/inc/v1" xmlns:ns2="http://schema.abc.nl/cdm/ins/v1"') = 1;

 OFFERTEID
----------
        42

您也可以使用通配符,但这并不理想:

SELECT offerteId 
FROM QUOTATIONS 
WHERE EXISTSNODE(XMLTYPE(XMLOfferte),
  '//*:workcontract/*:verzekeringnemer/*:werkgever/*:rekening') = 1;

 OFFERTEID
----------
        42

但是,existsnode() is deprecated,所以你应该使用xmlexists()而不管怎样,你可以将命名空间声明为XPath参数的一部分:

SELECT offerteId 
FROM QUOTATIONS 
WHERE XMLEXISTS('declare namespace workcontract="http://schema.abc.nl/cdm/inc/v1"; (: :)
  declare namespace raamwerkcontract="http://schema.abc.nl/cdm/inc/v1"; (: :)
  declare namespace ns2="http://schema.abc.nl/cdm/ins/v1"; (: :)
  /workcontract:workcontract/raamwerkcontract:verzekeringnemer/workcontract:werkgever/ns2:rekening'
  PASSING XMLTYPE(XMLOfferte)
);

 OFFERTEID
----------
        42