SOAP

2016-04-14 31 views
0

CDATA bölümünü ayrıştırmak için XMLTABLE kullanma XMLTABLE kullanarak SOAP yanıtının CDATA bölümünü nasıl ayrıştıracağınızı öğrenmek için bu thread örneğini izliyorum. Veritabanı, Oracle Database 11g Enterprise Edition 11.2.0.4.0.SOAP

Ayrıştırmam gereken SOAP yanıtını değiştirdim, böylece baktığım örneğe benzeyen bir sorguya sahip olabilirdim.

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; 

Ve bu sorgu sonuçları istediğim döndürür::

Yani bu biraz basitleştirilmiş tepki zarf ile de olsa, tamam çalışıyor budur

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 

Maalesef gerçek SABUN yanıtı ben Bu gibi ayrıştırmak gerekiyor:

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; 

Bu bit yüzünden, satır set xmlns = "urn: schemas-microsoft-com: xml-analysis: rowset", kodum artık çalışmıyor ve bundan nasıl geçeceğimi bilmiyorum. Sorguda bu SOAP yanıtını başarılı bir şekilde ayrıştıracak değişiklikler önerilebilirse, bu yardımı büyük ölçüde takdir ediyorum.

cevap

1

1) Secound sopa isteğiniz cdata'da geçersiz xml içeriyor.

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 

İade

<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> 

sen 1 xml (cdata) yolunda row elemana 2., /Data/row/rowset/row olmasıdır. 2. xml'de (cdata) ayrıca, xmlns="urn:schemas-microsoft-com:xml-analysis:rowset" varsayılan nam boşluğu bildirimi de vardır.

2. xmltable içindeki yolu '*/Row' olarak değiştirebilir ve xml ad boşluğundan kurtulabilirsiniz. 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

Mükemmel çalışıyor - İkinci xml eksik etiket için özür (örneğin şimdi onarıldı). Ve evet, çalıştığım örneğe benzemek için etiketini ekledim, ancak gerçek SOAP yanıtı varsayılan ad alanını ve satır kümesi etiketini içeriyor. Bu herifi geçmeme yardımın için teşekkür ederim. –