Oracle XMLTable如何从此XML中提取字段

时间:2019-02-28 16:20:50

标签: xml oracle soap

我正在尝试使用Oracle从以下XML中提取字段:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <ns2:check xmlns:ns2="http://soap.com" xmlns="http://soap.com/xsd">
      <ns2:request>
        <orderIDs>201902281425597269</orderIDs>
      </ns2:request>
    </ns2:check>
  </soap:Body>
</soap:Envelope>

我尝试了以下内容及其变体,但没有运气:

..
    XMLTable(XMLNAMESPACES (
      'http://soap.com/xsd' AS "ns2"
    ),
    'for $i in //orderIDs return $i'
    passing XMLType(sm.REQUEST_XML)
    columns "ORDER_ID" VARCHAR2(500) path '/') xt_orderid
..

以上是查询与其他表交叉连接的一部分。什么都不起作用,因为查询没有返回结果,所以我猜XMLTable命令变成空的。

非常类似的提取命令可用于响应,但是响应的结构不同。

1 个答案:

答案 0 :(得分:1)

您使用错误的路径声明了ns2,但无论如何您都没有引用它;由于orderIds没有命名空间前缀,因此您需要声明一个默认值(或同样):

XMLTable(XMLNAMESPACES (
  default 'http://soap.com/xsd', 'http://soap.com' AS "ns2"
),
'for $i in //orderIDs return $i'
passing XMLType(sm.REQUEST_XML)
columns "ORDER_ID" VARCHAR2(500) path '/') xt_orderid

这里也不需要for,可以使用更简单的路径;在CTE中使用示例数据进行演示:

with sm (request_xml) as (
  select '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <ns2:check xmlns:ns2="http://soap.com" xmlns="http://soap.com/xsd">
      <ns2:request>
        <orderIDs>201902281425597269</orderIDs>
      </ns2:request>
    </ns2:check>
  </soap:Body>
</soap:Envelope>' from dual
)
select xt_orderid.order_id
from sm
cross join
    XMLTable(XMLNAMESPACES (
      default 'http://soap.com/xsd'
    ),
    '//orderIDs'
    passing XMLType(sm.REQUEST_XML)
    columns "ORDER_ID" VARCHAR2(500) path '/') xt_orderid
/

ORDER_ID                                          
--------------------------------------------------
201902281425597269

您还可以通配符命名空间,但这并不理想,通常,如果静态的话,我宁愿给出完整路径(为每个节点提供适当的命名空间)。而且,如果您的XML仅具有一个订单ID,则可以使用XMLQuery代替XMLTable,但是我想您真的会从更大的文档中提取其他信息。