2016-04-14 3 views
0

Я следую примеру этого thread, чтобы узнать, как разбирать раздел CDATA ответа SOAP с помощью XMLTABLE. База данных - это Oracle Database 11g Enterprise Edition 11.2.0.4.0.Использование XMLTABLE для разбора раздела CDATA SOAP

Я изменил ответ 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; 

Из-за этого бита, строки set xmlns = "urn: schemas-microsoft-com: xml-analysis: rowset", мой код больше не работает, и я не знаю, как это пройти. Если кто-нибудь может предложить изменения в моем запросе, который успешно проанализирует этот ответ SOAP, я был бы очень признателен за помощь.

ответ

1

1) У вашего запроса sopa на sound есть недопустимый xml в cdata.

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. Во втором 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; 
+0

отлично работает - Извинения отсутствующий тег во втором XML (это теперь установлено в примере). И да, я добавил тег вокруг первого, чтобы он был похож на пример, с которого я работал, но фактический ответ SOAP включает пространство имен по умолчанию и тег набора строк. Благодарим вас за помощь в получении меня от этого горба. –

Смежные вопросы