【问题标题】:Parsing SOAP response using PL/SQL使用 PL/SQL 解析 SOAP 响应
【发布时间】:2017-08-30 08:20:16
【问题描述】:

我正在尝试使用以下代码解析 SOAP 响应,但我得到一个空响应。响应包含多个名称空间,我认为这就是我遇到问题的地方。有人能指出我做错了什么吗?

declare
  l_xml  xmltype;
begin
  l_xml := xmltype.createXML('<?xml version="1.0" encoding="UTF-8"?>
                <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.cachelan.com/WebAPI/solarvuDataRetrieve.php" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns2="http://xml.apache.org/xml-soap" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
                <SOAP-ENV:Body>
                    <ns1:getDataResponse>
                        <return xsi:type="ns2:Map">
                            <item>
                                <key xsi:type="xsd:string">status</key>
                                <value xsi:type="xsd:int">0</value>
                            </item>
                            <item>
                                <key xsi:type="xsd:string">content</key>
                                <value xsi:type="xsd:string">"SolarVu OM Data Request"
                                "From Mar 1, 2017 To Mar 4, 2017"

                                "Timestamp","Date","Daily Energy(kWh)","Insolation(Wh/m^2)"
                                "1488344400","Mar 1/17","131.064","1,105.750"
                                "1488430800","Mar 2/17","370.576","3,202.750"
                                "1488517200","Mar 3/17","517.566","4,662.500"
                                "1488603600","Mar 4/17","382.626","6,001.750"
                            </value>
                        </item>
                    </return>
                </ns1:getDataResponse>
                </SOAP-ENV:Body>
                </SOAP-ENV:Envelope>');

  for i in (SELECT t."key", t."value"
            FROM dual d,
            XMLTABLE(xmlnamespaces('http://www.w3.org/2001/XMLSchema-instance' as "xsi",
                                   'http://schemas.xmlsoap.org/soap/envelope/' as "SOAP-ENV",
                                   'http://www.cachelan.com/WebAPI/solarvuDataRetrieve.php' as "ns1",
                                   'http://www.w3.org/2001/XMLSchema' as "xsd",
                                   'http://xml.apache.org/xml-soap' as "ns2",
                                   'http://schemas.xmlsoap.org/soap/encoding/' as "SOAP-ENC"), 
                    '/getDataResponse/return/item[*]'
              PASSING l_xml
              COLUMNS 
                 "key"   varchar2(4000) PATH 'key',
                 "value" varchar2(4000) PATH 'value') t)
  loop
    dbms_output.put_line('Key is: '||i."key");
  end loop;
end;
/

【问题讨论】:

    标签: xml oracle soap plsql


    【解决方案1】:

    我有同样的问题。我发现问题出在 &lt;ns1:getDataResponse&gt; 之类的前缀命名空间中,以及 Oracle XMLType 如何解释它们。根据您的示例,我解决了提取没有前缀命名空间的内部节点的问题。

    declare
       l_xml xmltype;
    begin
       l_xml := xmltype.createXML('<?xml version="1.0" encoding="UTF-8"?>
                    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.cachelan.com/WebAPI/solarvuDataRetrieve.php" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns2="http://xml.apache.org/xml-soap" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
                    <SOAP-ENV:Body>
                        <ns1:getDataResponse>
                            <return xsi:type="ns2:Map">
                                <item>
                                    <key xsi:type="xsd:string">status</key>
                                    <value xsi:type="xsd:int">0</value>
                                </item>
                                <item>
                                    <key xsi:type="xsd:string">content</key>
                                    <value xsi:type="xsd:string">"SolarVu OM Data Request"
                                    "From Mar 1, 2017 To Mar 4, 2017"
    
                                    "Timestamp","Date","Daily Energy(kWh)","Insolation(Wh/m^2)"
                                    "1488344400","Mar 1/17","131.064","1,105.750"
                                    "1488430800","Mar 2/17","370.576","3,202.750"
                                    "1488517200","Mar 3/17","517.566","4,662.500"
                                    "1488603600","Mar 4/17","382.626","6,001.750"
                                </value>
                            </item>
                        </return>
                    </ns1:getDataResponse>
                    </SOAP-ENV:Body>
                    </SOAP-ENV:Envelope>');
    
       --Pay attention here and changes in path parameter at XMLTABLE
       l_xml := l_xml.EXtract('//*/*//return');
    
       for i in (select t.key, t.value
                   from dual d,
                        XMLTABLE('/return/item' PASSING l_xml COLUMNS key
                                   varchar2(4000) PATH 'key',
                                  value varchar2(4000) PATH 'value') t) loop
          dbms_output.put_line('Key is: ' || i.key);
       end loop;
    end;
    

    【讨论】:

    • 谢谢你给 Seyran 的小费,下次我会把这个技巧放在包里。
    • 这看起来有点像 hack,如果您需要来自多个返回节点或一个节点内的多个层的数据,特别是如果任何有命名空间的话,这将不会真正起作用。如果你这样做,xmlnamespaces 子句是多余的,因为提取的节点没有命名空间前缀。
    • @Alex Poole 它有指向命名空间类型 ex 的链接。 &lt;key xsi:type="xsd:string"&gt; 如果省略 xmlnamespace 你会得到一个错误。
    • 我运行您的代码,删除了xmlnamespaces 子句,它运行良好。在这种情况下,命名空间位于未引用的属性上,所以我猜它没有被检查?
    • 抱歉同意@Alex Poole。
    【解决方案2】:

    您没有在 XPath 中为其命名空间添加 getDataResponse 前缀,也没有包含信封和正文标记;所以将 XPath 更改为:

    '/SOAP-ENV:Envelope/SOAP-ENV:Body/ns1:getDataResponse/return/item'
    

    只需更改您的代码即可生成:

    Key is: status
    Key is: content
    
    PL/SQL procedure successfully completed.
    

    【讨论】:

    • 谢谢 Alex,我根据您的建议完成了这项工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-26
    • 1970-01-01
    • 1970-01-01
    • 2020-04-22
    • 1970-01-01
    相关资源
    最近更新 更多