Oracle XMLTable如何从此XML提取字段

Oracle XMLTable如何从此XML提取字段,xml,oracle,soap,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>

我正在尝试使用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命令是空的

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

您使用错误的路径声明ns2,但无论如何都不会引用它;由于OrderID没有名称空间前缀,因此您需要声明默认值,或者:

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,但我想您真的会从一个更大的文档中提取其他信息。

谢谢@Alex Poole,看来我的默认名称空间是错误的。现在可以了。
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