使用XMLTABLE解析SOAP的CDATA部分

时间:2016-04-14 04:28:54

标签: xml oracle web-services soap

我按照此thread中的示例来学习如何使用XMLTABLE解析SOAP响应的CDATA部分。数据库是Oracle Database 11g企业版11.2.0.4.0。

我修改了我需要解析的SOAP响应,因此我可以使用一个有效的查询,类似于我正在查看的示例。

所以这就是正常工作,尽管响应范围略微简化:

CREATE TABLE xml_tab (xml_data xmltype);

DECLARE l
l_xmltype xmltype;

BEGIN

SELECT xmltype('<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:sawsoap="urn://oracle.bi.webservices/v6">  
<soap:Body>    
<sawsoap:executeSQLQueryResult>      
<sawsoap:return xsi:type="sawsoap:QueryResults">        
<sawsoap:rowset><![CDATA[<Data><Row><Column0>1200</Column0><Column1>East Region</Column1></Row><Row><Column0>3000</Column0><Column1>West Region</Column1></Row></Data>]]></sawsoap:rowset>        
<sawsoap:queryID/>        
<sawsoap:finished>true</sawsoap:finished>      
</sawsoap:return>    
</sawsoap:executeSQLQueryResult>  
</soap:Body>
</soap:Envelope>') INTO l_xmltype FROM dual ;

INSERT INTO xml_tab VALUES(l_xmltype);

END;

此查询返回我想要的结果:

SELECT B2.*  
   FROM 
   xml_tab x,
   XMLTable(  
         XMLNamespaces(  
           'http://schemas.xmlsoap.org/soap/envelope/' AS "SOAP-ENV"  
            ,'urn://oracle.bi.webservices/v6' AS  "sawsoap"                
          )  
        , 'SOAP-ENV:Envelope/SOAP-ENV:Body/sawsoap:executeSQLQueryResult/sawsoap:return/sawsoap:rowset'  
          passing    x.XML_DATA 
          columns Row1 clob path '.'  
       ) A1,
        XMLTable(  
         '/Data/Row'  
         passing xmlparse(document A1.Row1)  
         columns    
         Amount number PATH 'Column0',
         Region varchar2(60) PATH 'Column1'
       ) B2;



AMOUNT REGION                                                     
  ---------- ------------------------------------------------------------
  1200 East Region                                                  
  3000 West Region 

不幸的是,我需要解析的实际SOAP响应如下所示:

truncate table xml_tab;

 DECLARE
  l_xmltype xmltype;
BEGIN
  SELECT xmltype('<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:sawsoap="urn://oracle.bi.webservices/v6">
  <soap:Body>
    <sawsoap:executeSQLQueryResult>
      <sawsoap:return xsi:type="sawsoap:QueryResults">
        <sawsoap:rowset><![CDATA[<rowset xmlns="urn:schemas-microsoft-com:xml-analysis:rowset" ><Row><Column0>01200</Column0><Column1>East Region</Column1></Row><Row><Column0>3000</Column0><Column1>West Region</Column1></Row></rowset>]]></sawsoap:rowset>
        <sawsoap:queryID/>
        <sawsoap:finished>true</sawsoap:finished>
      </sawsoap:return>
    </sawsoap:executeSQLQueryResult>
  </soap:Body>
</soap:Envelope>')
  INTO l_xmltype
  FROM dual ;
  INSERT INTO xml_tab VALUES
    (l_xmltype
    );
END;

由于这一点,行集xmlns =&#34; urn:schemas-microsoft-com:xml-analysis:rowset&#34;,我的代码不再有效,我不知道如何通过这个。如果有人可以建议修改我的查询将成功解析这个SOAP响应,我将非常感谢帮助。

1 个答案:

答案 0 :(得分:1)

1)你的secound sopa请求在cdata中有无效的xml。

SELECT A1.Row1  
   FROM 
   xml_tab x,
   XMLTable(  
         XMLNamespaces(  
           'http://schemas.xmlsoap.org/soap/envelope/' AS "SOAP-ENV"  
            ,'urn://oracle.bi.webservices/v6' AS  "sawsoap"                
          )  
        , 'SOAP-ENV:Envelope/SOAP-ENV:Body/sawsoap:executeSQLQueryResult/sawsoap:return/sawsoap:rowset'  
          passing    x.XML_DATA 
          columns Row1 clob path '.'  
       ) A1

返回

<rowset xmlns="urn:schemas-microsoft-com:xml-analysis:rowset" >
  <Row>
    <Column0>01200/Column0>   --<-- invalid tag column0 isn't closed
    <Column1>East Region</Column1>
    </Row>
  <Row>
    <Column0>3000</Column0>
    <Column1>West Region</Column1>
    </Row>
</rowset>

在第一个row元素的第一个xml(cdata)路径{2}中的/Data/row/rowset/row。 在第二个xml(cdata)中也存在默认namsespace xmlns="urn:schemas-microsoft-com:xml-analysis:rowset"的声明。

您可以将第二个xmltable中的路径更改为'*/Row'并删除xml命名空间。   passing xmlparse(document regexp_replace(A1.Row1,'xmlns=".*"', ''))

  SELECT  B2.*
       FROM 
       xml_tab x,
       XMLTable(  
             XMLNamespaces(  
               'http://schemas.xmlsoap.org/soap/envelope/' AS "SOAP-ENV"  
                ,'urn://oracle.bi.webservices/v6' AS  "sawsoap"                
              )  
            , 'SOAP-ENV:Envelope/SOAP-ENV:Body/sawsoap:executeSQLQueryResult/sawsoap:return/sawsoap:rowset'  
              passing    x.XML_DATA 
              columns Row1 clob path '.'  
           ) A1
          ,
            XMLTable(  
             '/*/Row'  
            passing xmlparse(document regexp_replace(A1.Row1,'xmlns=".*"', ''))  
             columns    
            Amount number PATH 'Column0',
            Region varchar2(60) PATH 'Column1'
          ) B2;