1 Reply Latest reply on Nov 13, 2013 10:24 PM by Jason_(A_Non)

    Problem extracting the content of a big xml data

    Verlingue

      Hello

       

      I'm trying to use a web service that needs and returns big messages (>1Mo).

      Could you tell me if I do something wrong ? (I have a problem with the extract function at the end of the process)

       

      For this I modified the soap_api package to use clob for the envelope instead of varchar2.

      Sending a message works well, I modified the part of the invoke function that does this to

      send the message chunked :

       

       

      generate_envelope(p_request, l_envelope, p_type);

      --show_envelope(l_envelope);

      l_http_request := UTL_HTTP.begin_request(p_url, 'POST','HTTP/1.1');

      UTL_HTTP.set_header(l_http_request, 'Content-Type', 'text/xml');

      UTL_HTTP.set_header(l_http_request, 'Content-Length', LENGTH(l_envelope));

      UTL_HTTP.set_header(l_http_request, 'Transfer-Encoding', 'chunked' );

      UTL_HTTP.set_header(l_http_request, 'SOAPAction', p_action);

       

      --UTL_HTTP.write_text(l_http_request, l_envelope);

      v_clob_length := dbms_lob.getlength(l_envelope);

      loop

          if (v_end > v_clob_length) then

              v_end := v_clob_length;

              v_length := v_end - v_start + 1;

          end if;

       

          v_chunk_data := null;

          v_chunk_data := DBMS_LOB.SUBSTR(l_envelope, v_length, v_start);

       

          UTL_HTTP.write_text(l_http_request, v_chunk_data );

       

          if (v_end = v_clob_length) then

              exit;

          end if;

       

          v_start := v_end + 1;

          v_end := v_start + 2000;

       

      end loop;

       

       

      After that I modified the function to retrieve the message line by line instead of in one block :

       

      l_http_response := UTL_HTTP.get_response(l_http_request);

      --UTL_HTTP.read_text(l_http_response, l_envelope);

      l_envelope := null;

      begin

        LOOP

          utl_http.read_line(l_http_response, v_line, TRUE);

          v_line_clob := v_line;

          l_envelope := l_envelope || v_line_clob;

        END LOOP;

       

      UTL_HTTP.end_response(l_http_response);

       

      exception

        WHEN utl_http.end_of_body THEN

          utl_http.end_response(l_http_response);

      end;

       

      --show_envelope(l_envelope);

       

      l_response.doc := XMLTYPE(l_envelope);

      l_response.envelope_tag := p_request.envelope_tag;

       

      (I modified the show_envelope function to save the xml in a file and the message is completed and the creation of the xmltype returns no errors)

       

      But the last part that I didn't change doesn't work :

       

      l_response.doc := l_response.doc.extract('/' || l_response.envelope_tag || ':Envelope/' || l_response.envelope_tag || ':Body/child::node()',

                          'xmlns:' || l_response.envelope_tag || '="http://schemas.xmlsoap.org/soap/envelope/"');

      show_envelope(l_envelope);

       

      It should remove the <soap:Envelope> and <sopa:Body> part but they still exists after the extract.

      This is an example of the xml I receive from the web service :

       

      <?xml version="1.0" encoding="utf-8"?><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"><soap:Body><getResultTestRetourStringResult xmlns="http://www.verlingue.fr/WSCalculTarificateur/"><Resultat>

      ...

      ...

      ...

      </Resultat></getResultTestRetourStringResult></soap:Body></soap:Envelope>

        • 1. Re: Problem extracting the content of a big xml data
          Jason_(A_Non)

          Maybe because you are using l_envelope when calling show_envelop?

          l_response.doc := l_response.doc.extract('/' || l_response.envelope_tag || ':Envelope/' || l_response.envelope_tag || ':Body/child::node()',

                              'xmlns:' || l_response.envelope_tag || '="http://schemas.xmlsoap.org/soap/envelope/"');

          show_envelope(l_envelope);

          It's really hard to tell from your snippets of code, some of which have nothing to do with the issue.  The following works for me just fine on 11.1.0.6

          declare 
            l_doc   XMLTYPE;
            l_snip  XMLTYPE;
          begin
            l_doc := XMLTYPE('<?xml version="1.0" encoding="utf-8"?>
          <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">
             <soap:Body>
                <getResultTestRetourStringResult xmlns="http://www.verlingue.fr/WSCalculTarificateur/">
                   <Resultat></Resultat>
                </getResultTestRetourStringResult>
              </soap:Body>
          </soap:Envelope>');
          
            l_snip := l_doc.extract('/a:Envelope/a:Body/*','xmlns:a="http://schemas.xmlsoap.org/soap/envelope/"');
            dbms_output.put_line(l_snip.getStringVal);
            
          end;
          

          produces

          <getResultTestRetourStringResult xmlns="http://www.verlingue.fr/WSCalculTarificateur/">
            <Resultat/>
          </getResultTestRetourStringResult>
          
          

          I also get the same thing when using child::node() instead of *

           

          You'll notice that my namespace prefixes do not agree with what's in the XML.  That's okay.  Only the URI matters, not the prefix itself.  Since your URI is hard-coded, you could simplify the XPath as I showed so that it is easier to read.

           

          Welcome to the forums.

          Here is an always helpful read.

          Re: 2. How do I ask a question on the forums?