首页 > 解决方案 > 提取 XML 值

问题描述

这是我的 xml 消息:

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:wsa="http://www.w3.org/2005/08/addressing">
 <env:Header>
 <wsa:Action>http://xmlns.oracle.com/apps/hcm/trees/organizationTreeService//OrganizationTreeService/addValueOrganizationTreeNodeResponse</wsa:Action>
 <wsa:MessageID>urn:uuid:d8f54d7e-8319-492a-9e0f-ec48ba2e840c</wsa:MessageID></env:Header><env:Body>
 <ns0:addValueOrganizationTreeNodeResponse xmlns:ns0="http://xmlns.oracle.com/apps/hcm/trees/organizationTreeService/types/">
 <ns2:treeNodeId xmlns:ns2="http://xmlns.oracle.com/apps/hcm/trees/organizationTreeService/types/" xmlns:ns1="http://xmlns.oracle.com/apps/hcm/trees/organizationTreeService/" xmlns:tns="http://xmlns.oracle.com/adf/svc/errors/" xmlns:ns0="http://xmlns.oracle.com/adf/svc/types/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns0:StringResult">
 <ns0:Value>80CF98290891BB06E053C8B0BB0A2848</ns0:Value></ns2:treeNodeId></ns0:addValueOrganizationTreeNodeResponse>
 </env:Body></env:Envelope>

我需要从此 xml 消息中获取 value80CF98290891BB06E053C8B0BB0A2848

我正在尝试将此代码放入 xmltable 中,然后放入 mt 自定义表中

select  y.JobFamilyId 
  INTO L_PARENTTRENODEID  

 from (select xmltype (P_RESPONSE) xml from dual) t, 
     xmltable(
  xmlnamespaces ( 'http://xmlns.oracle.com/apps/hcm/trees/organizationTreeService/' as "ns0" ),
  '//ns1:value'
  passing t.xml
  columns
 value varchar2(500) path '/*:value'
 ) x 

标签: sqlxmloracleplsql

解决方案


您为ns0命名空间提供的路径从头到尾都缺少/types- 尽管您使用了错误的 URL,但无论如何ns0它实际上对Value节点有效;您的 XPath 具有ns1:value而不是,ns0:Value但要么需要通配符,要么具有完整路径;并且该columns子句可以简化为'.'

select x.value
into l_parenttrenodeid  
from xmltable(
  xmlnamespaces('http://xmlns.oracle.com/adf/svc/types/' as "ns0"),
  '//ns0:Value'
  passing xmltype(p_response)
  columns value varchar2(500) path '.'
) x;

或通配符(无需 NS 声明):

select x.value
into l_parenttrenodeid  
from xmltable(
  '//*:Value'
  passing xmltype(p_response)
  columns value varchar2(500) path '.'
) x;

或使用该节点的完整 XPath(此处拆分,以便部分进入columns子句,为了好玩并减少滚动),并声明该路径中的所有名称空间 - 这令人困惑,因为至少一个 URL 用于多个名称,并且在至少一个名称用于多个 URL。幸运的是,名称不必匹配,它们只需要解析到正确的路径:

select x.value
into l_parenttrenodeid  
from xmltable(
  xmlnamespaces(
    'http://schemas.xmlsoap.org/soap/envelope/' as "env",
    'http://xmlns.oracle.com/apps/hcm/trees/organizationTreeService/types/' as "ns1",
    'http://xmlns.oracle.com/adf/svc/types/' as "ns2"
  ),
  '/env:Envelope/env:Body/ns1:addValueOrganizationTreeNodeResponse/ns1:treeNodeId'
  passing xmltype(p_response)
  columns value varchar2(500) path 'ns2:Value'
) x;

您也可以使用XMLQuery()call 而不是XMLTable(),因为您只期望一个结果:

select xmlquery(
  'declare namespace env = "http://schemas.xmlsoap.org/soap/envelope/"; (::)
    declare namespace ns1 = "http://xmlns.oracle.com/apps/hcm/trees/organizationTreeService/types/"; (::)
    declare namespace ns2 = "http://xmlns.oracle.com/adf/svc/types/"; (::)
    /env:Envelope/env:Body/ns1:addValueOrganizationTreeNodeResponse/ns1:treeNodeId/ns2:Value/text()'
  passing xmltype(p_response)
  returning content
).getstringval()
into l_parenttrenodeid
from dual;

推荐阅读