【问题标题】:Oracle XMLTable how to extract a field from this XMLOracle XMLTable 如何从此 XML 中提取字段
【发布时间】:2019-07-22 15:03:05
【问题描述】:

我正在尝试使用 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 命令变成了空。

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

【问题讨论】:

    标签: xml oracle soap


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

    【讨论】:

    • 谢谢@Alex Poole,看来我的默认命名空间是错误的。现在可以了。
    猜你喜欢
    • 2016-04-28
    • 2017-12-06
    • 2015-12-21
    • 2014-08-14
    • 2015-08-12
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 2011-09-13
    相关资源
    最近更新 更多