【问题标题】:extract elements from xml in PL/SQl从 PL/SQl 中的 xml 中提取元素
【发布时间】:2013-07-30 16:55:24
【问题描述】:

以下是 SOAP 服务的响应。我如何在 Pl/SQL 中提取值。我列出了一些我尝试过的方法

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
   <ShipmentTrackingResponse xmlns="http://ws.aramex.net/ShippingAPI/v1/">
    <Transaction xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
     <Reference1>001</Reference1>
     <Reference2 i:nil="true"/>
     <Reference3 i:nil="true"/>
     <Reference4 i:nil="true"/>
     <Reference5 i:nil="true"/>
    </Transaction>
    <Notifications xmlns:i="http://www.w3.org/2001/XMLSchema-instance"/>   
    <HasErrors>false</HasErrors>
    <TrackingResults xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
     <a:KeyValueOfstringArrayOfTrackingResultmFAkxlpY>
      <a:Key>4738079651</a:Key>
      <a:Value>
      <TrackingResult>
       <WaybillNumber>4738079651</WaybillNumber>
       <UpdateCode>SH247</UpdateCode>
       <UpdateDescription>Supporting Document Returned to Shipper</UpdateDescription>
       <UpdateDateTime>2013-07-15T19:29:00</UpdateDateTime> 
       <UpdateLocation>Mumbai,India</UpdateLocation>
       <Comments/>
       <ProblemCode/>
      </TrackingResult>

      <TrackingResult>
       <WaybillNumber>4738079651</WaybillNumber>
       <UpdateCode>SH369</UpdateCode>
       <UpdateDescription>SMS Sent to Consignee</UpdateDescription>
       <UpdateDateTime>2013-07-12T09:10:00</UpdateDateTime>   
       <UpdateLocation>Mumbai,India</UpdateLocation>
       <Comments/>
       <ProblemCode/>
      </TrackingResult>

      <TrackingResult>
       <WaybillNumber>4738079651</WaybillNumber>
       <UpdateCode>SH033</UpdateCode>
       <UpdateDescription>Attempted Delivery - Payment Declined by Customer</UpdateDescription>
       <UpdateDateTime>2013-07-11T17:20:00</UpdateDateTime>
       <UpdateLocation>Goa Branch-GOI,India</UpdateLocation>
       <Comments/>
       <ProblemCode>A18</ProblemCode>
      </TrackingResult>

      <TrackingResult>
       <WaybillNumber>4738079651</WaybillNumber>
       <UpdateCode>SH369</UpdateCode>
       <UpdateDescription>SMS Sent to Consignee</UpdateDescription>
       <UpdateDateTime>2013-07-11T10:36:00</UpdateDateTime>
       <UpdateLocation>Mumbai,India</UpdateLocation>
       <Comments/>
       <ProblemCode/>
      </TrackingResult>

      <TrackingResult>
       <WaybillNumber>4738079651</WaybillNumber>
       <UpdateCode>SH003</UpdateCode>
       <UpdateDescription>Out for Delivery</UpdateDescription>
       <UpdateDateTime>2013-07-11T10:19:00</UpdateDateTime>
       <UpdateLocation>Goa Branch-GOI,India</UpdateLocation>
       <Comments/>
       <ProblemCode/>
      </TrackingResult>

      <TrackingResult>
       <WaybillNumber>4738079651</WaybillNumber>
       <UpdateCode>SH203</UpdateCode>
       <UpdateDescription>Record Created</UpdateDescription>
       <UpdateDateTime>2013-07-05T00:39:00</UpdateDateTime>
       <UpdateLocation>Nehru Place Branch,India</UpdateLocation>
       <Comments/>
       <ProblemCode/>
      </TrackingResult>
    </a:Value>
   </a:KeyValueOfstringArrayOfTrackingResultmFAkxlpY>
  </TrackingResults>
<NonExistingWaybills xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays" 
xmlns:i="http://www.w3.org/2001/XMLSchema-instance"/></ShipmentTrackingResponse></s:Body>
</s: Envelope>

我如何提取值,我真的被卡住了,已经尝试了所有方法。 部分方法如下:

l_resp_xml := XMLType.createXML(l_clob_response);
SELECT EXTRACT(l_resp_xml, '//ShipmentTrackingResponse/TrackingResults',
 'xmlns="http://ws.aramex.net/ShippingAPI/v1/"') INTO l_resp_xml FROM dual;

最后用于提取值:但没用! 请帮忙!!

SELECT EXTRACTVALUE(l_resp_xml, 
'//TrackingResults/a:KeyValueOfstringArrayOfTrackingResultmFAkxlpY/a:Value/TrackingResult[1]/UpdateDescription', 'xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"')INTO l_response_result FROM dual;
DBMS_OUTPUT.put_line ( 'Result> l_response_clobExtract=' || l_response_result);

如何使用XmlTable?

【问题讨论】:

    标签: xml oracle plsql xml-parsing extract


    【解决方案1】:

    您需要向下/到特定的 XML 标记/节点

     SELECT *
       FROM XMLTable('$dat//xmlpath' --the path to the node you want to start reading from
                       PASSING your_xml_node AS "dat"
                       COLUMNS
                           vcol NUMBER PATH 'col_path', --from your given node
                           ...etc
                        ) ;
    

    对于您要读取的每个 XML 值,您需要在 COLUMNS 下添加一列并将其映射到给定 XML 节点中的路径

    您可以在Oracle Docs阅读更多内容



    EDIT 我使用了您在 OP 中列出的 XML,您可以这样做(我无法访问您的 http://ws.aramex.net/ShippingAPI/v1/ 架构,所以我使用了* 查询任何架构/命名空间)。

    处理XML时最重要的事情是路径,你没有得到任何结果的原因是因为你在路径的某个地方出了问题。我花了一段时间才学会这个,祝你好运:)

        SELECT *
          FROM XMLTABLE (
                  xmlnamespaces (
                     'http://schemas.xmlsoap.org/soap/envelope/' AS "s",
                     'http://schemas.microsoft.com/2003/10/Serialization/Arrays' AS "a"),
                  '$xd/s:Envelope/s:Body/*:ShipmentTrackingResponse/*:TrackingResults/a:KeyValueOfstringArrayOfTrackingResultmFAkxlpY'
                  PASSING xmltype (
                             '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
      <s:Body>
       <ShipmentTrackingResponse xmlns="http://ws.aramex.net/ShippingAPI/v1/">
        <Transaction xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
         <Reference1>001</Reference1>
         <Reference2 i:nil="true"/>
         <Reference3 i:nil="true"/>
         <Reference4 i:nil="true"/>
         <Reference5 i:nil="true"/>
        </Transaction>
        <Notifications xmlns:i="http://www.w3.org/2001/XMLSchema-instance"/>   
        <HasErrors>false</HasErrors>
        <TrackingResults xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
         <a:KeyValueOfstringArrayOfTrackingResultmFAkxlpY>
          <a:Key>4738079651</a:Key>
          <a:Value>
          <TrackingResult>
           <WaybillNumber>4738079651</WaybillNumber>
           <UpdateCode>SH247</UpdateCode>
           <UpdateDescription>Supporting Document Returned to Shipper</UpdateDescription>
           <UpdateDateTime>2013-07-15T19:29:00</UpdateDateTime> 
           <UpdateLocation>Mumbai,India</UpdateLocation>
           <Comments/>
           <ProblemCode/>
          </TrackingResult>
    
          <TrackingResult>
           <WaybillNumber>4738079651</WaybillNumber>
           <UpdateCode>SH369</UpdateCode>
           <UpdateDescription>SMS Sent to Consignee</UpdateDescription>
           <UpdateDateTime>2013-07-12T09:10:00</UpdateDateTime>   
           <UpdateLocation>Mumbai,India</UpdateLocation>
           <Comments/>
           <ProblemCode/>
          </TrackingResult>
    
          <TrackingResult>
           <WaybillNumber>4738079651</WaybillNumber>
           <UpdateCode>SH033</UpdateCode>
           <UpdateDescription>Attempted Delivery - Payment Declined by Customer</UpdateDescription>
           <UpdateDateTime>2013-07-11T17:20:00</UpdateDateTime>
           <UpdateLocation>Goa Branch-GOI,India</UpdateLocation>
           <Comments/>
           <ProblemCode>A18</ProblemCode>
          </TrackingResult>
    
          <TrackingResult>
           <WaybillNumber>4738079651</WaybillNumber>
           <UpdateCode>SH369</UpdateCode>
           <UpdateDescription>SMS Sent to Consignee</UpdateDescription>
           <UpdateDateTime>2013-07-11T10:36:00</UpdateDateTime>
           <UpdateLocation>Mumbai,India</UpdateLocation>
           <Comments/>
           <ProblemCode/>
          </TrackingResult>
    
          <TrackingResult>
           <WaybillNumber>4738079651</WaybillNumber>
           <UpdateCode>SH003</UpdateCode>
           <UpdateDescription>Out for Delivery</UpdateDescription>
           <UpdateDateTime>2013-07-11T10:19:00</UpdateDateTime>
           <UpdateLocation>Goa Branch-GOI,India</UpdateLocation>
           <Comments/>
           <ProblemCode/>
          </TrackingResult>
    
          <TrackingResult>
           <WaybillNumber>4738079651</WaybillNumber>
           <UpdateCode>SH203</UpdateCode>
           <UpdateDescription>Record Created</UpdateDescription>
           <UpdateDateTime>2013-07-05T00:39:00</UpdateDateTime>
           <UpdateLocation>Nehru Place Branch,India</UpdateLocation>
           <Comments/>
           <ProblemCode/>
          </TrackingResult>
        </a:Value>
       </a:KeyValueOfstringArrayOfTrackingResultmFAkxlpY>
      </TrackingResults>
    <NonExistingWaybills xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays" 
    xmlns:i="http://www.w3.org/2001/XMLSchema-instance"/></ShipmentTrackingResponse></s:Body>
    </s:Envelope>') AS "xd"
                  COLUMNS key_col NUMBER PATH 'a:Key',
                          values_col XMLTYPE PATH 'a:Value') xx;
    

    【讨论】:

    • 感谢您的帮助,但是默认命名空间呢,这是卡住的地方。可以举个例子吗
    • 我做了以下事情:SELECT EXTRACT(l_resp_xml, '//s:Envelope/s:Body/node()', l_NAMESPACE_SOAP) INTO l_resp_xml FROM dual;
    • 然后:SELECT xx.UPDATEDESCRIPTION into l_response_message from xmltable(xmlnamespaces('http://ws.aramex.net/ShippingAPI/v1/' AS "a", 'http://schemas.microsoft.com/2003/10/Serialization/Arrays' AS "n"), '/ShipmentTrackingResponse/a:TrackingResults/n:KeyValueOfstringArrayOfTrackingResultmFAkxlpY/n:Value/n:TrackingResult[1]' passing l_resp_xml columns UPDATEDESCRIPTION VARCHAR2(128) path 'n:UpdateDescription[1]') xx; DBMS_OUTPUT.put_line('Result&gt; Update Description='|| l_response_message);
    • 可惜没用!!
    • 它说没有找到数据!!
    【解决方案2】:

    感谢贾法尔的帮助。我做了以下工作,效果很好!!解决了…………

    select x.UPDATEDESCRIPTION , x.UpdateDateTime into l_response_message, l_response_result from (select XMLType.createxml(l_clob_response) xml from dual) t, xmltable( xmlnamespaces ( 'http://ws.aramex.net/ShippingAPI/v1/' as "e", 'http://schemas.microsoft.com/2003/10/Serialization/Arrays' as "a", 'http://schemas.xmlsoap.org/soap/envelope/' as "s", default 'http://ws.aramex.net/ShippingAPI/v1/' ), 's:Envelope/s:Body/ShipmentTrackingResponse/TrackingResults/a:KeyValueOfstringArrayOfTrackingResultmFAkxlpY/a:Value/TrackingResult[1]' passing t.xml columns UpdateDescription varchar2(128) path 'UpdateDescription', UpdateDateTime varchar2(128) path 'UpdateDateTime' ) x; dbms_output.put_line('The UpdateDescription =>' || l_response_message); dbms_output.put_line('The UpdateDateTime =>' || l_response_result);

    【讨论】:

    • 很高兴为您提供帮助..如果我的帖子确实回答了您的问题,请将其标记为答案,以帮助以后会来这里的其他人..thnx
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多