2016-04-14 89 views
0

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

我修改了我需要解析的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 =“urn:schemas-microsoft-com:xml-analysis:rowset”,我的代码不再起作用,我不知道如何摆脱这种情况。如果任何人都可以建议对我的查询进行修改,以便成功解析此SOAP响应,我将非常感谢帮助。

回答

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> 

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

您可以将2nd 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; 
+0

完美的作品 - 在第二个XML缺少的标记道歉(它现在固定的例子)。是的,我添加了第一个标签以类似于我工作的示例,但实际的SOAP响应包含默认名称空间和行集标记。感谢你帮助我渡过这个坎坷。 –