10/11/2020
Fetch SOAP web service call with deep structure in ABAP [Part III]
This will be the last article that concludes the blog about fetching web service calls with deep structure into ABAP. Here we will review the ABAP code used to fetch the data into internal tables. If you haven’t read the 2 previous articles, please check them first at Part I and Part II
Now that we have a simple transformation we can start writing our program to fetch the data into the internal tables.
First, go to SE37 where we are going to create the function module which will call the SOAP request so we can retrieve the raw data.
Here is the full code I explain below the parameters that need to be changed in detail:
FUNCTION ZWS_SVOI.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" CHANGING
*" REFERENCE(ET_XML_TABLE) TYPE STRING
*"----------------------------------------------------------------------
DATA: lo_http_client TYPE REF TO if_http_client,
lv_url TYPE string,
lv_result TYPE xSTRING,
lv_payload TYPE string,
lv_payload_x TYPE xstring,
value TYPE string,
name type string.
cl_http_client=>create_by_url(
EXPORTING
url = 'http://YourSOAPURL'
********only need this code if proxy used*******
proxy_host = 'host'
proxy_service = 'port'
ssl_id = 'ID'
IMPORTING
client = lo_http_client
EXCEPTIONS
argument_not_found = 1
plugin_not_active = 2
internal_error = 3
OTHERS = 4 ).
*SOAP ENVELOPE
lv_payload = 'SOAP Body'.
*Convert string to Xstring
CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
EXPORTING
text = lv_payload
IMPORTING
buffer = lv_payload_x.
*SOAP POST request no authentication
lo_http_client->request->set_method( 'POST' ).
lo_http_client->request->set_content_type( 'text/xml' ).
lo_http_client->request->set_data( lv_payload_x ).
lo_http_client->request->set_header_field( name = 'SOAPAction' value = 'YourSOAPAction' ).
lo_http_client->send(
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2 ).
lo_http_client->receive(
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3 ).
DATA http_rc TYPE sy-subrc.
*status of the call
lo_http_client->response->get_status( IMPORTING code = http_rc ).
CLEAR lv_result.
lv_result = lo_http_client->response->get_data( ).
DATA lo_conv TYPE REF TO CL_ABAP_CONV_IN_CE.
DATA c_content TYPE string.
*convert to UTF-8 string
CALL METHOD cl_abap_conv_in_ce=>create
EXPORTING
encoding = 'UTF-8'
endian = 'L'
ignore_cerr = 'X'
replacement = '#'
input = lv_result
RECEIVING
conv = lo_conv.
CALL METHOD lo_conv->read
IMPORTING
data = c_content.
call method lo_http_client->close
exceptions http_invalid_state = 1
others = 2.
ET_XML_TABLE = c_content.
ENDFUNCTION.
Ok, so the parameters that need to be changed in cl_http_client=>create_by_url.
All parameters come from the SOAPUI call that we did in the beginning, so I again suggest you take this next to you for filling in the correct parameters.

URL is number 1 on the image
proxy_host, proxy_service, ssl_id you only need these if your company uses a proxy, you’ll have to ask these parameters to your security or networking team.
lv_payload is the SOAPBody and is number 2 in the image.
set_header_field( name = 'SOAPAction' value = 'YourSOAPAction' )
In order to call a SOAP request you need to implement the SOAPAction this can be found as number 3 in the image, note you need to be in the WS-A tab. You can find more info on it: here
So what this code does is: do the SOAP call retrieve the data of that call and then convert it to UTF-8 and store it in a STRING.
The easiest way to test if the code is working is by going into debug mode and check the C_CONTENT variable with XML view:

If you are having errors on the call of lv_result, you should check if the SOAP web service is accessible and working. My preferred way of doing this is by using Postman. Select the POST option to enter the URL. For the headers, tab set the following 2: Content-Type with text/xml and SOAPAction with your soap action as explained above. For the body, tab select raw and enter your body found in the SOAPUI. If you press send and you are able to retrieve the data here, it should also be accessible in ABAP. If not, you first must backtrace why your call isn’t working.
So now that we have the raw data, we want to use the simple transformation in a program to fetch the data into the corresponding fields of the structures we created at the start. And use this to fill up the internal tables.
So, go to transaction SE38 and create a new program.
I will again first post the complete code and then give some more info on it:
*&---------------------------------------------------------------------*
*& Report Z_XML_TO_ITAB
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT z_xml_to_itab_mode.
TYPE-POOLS abap.
DATA: gs_create_nomin TYPE zsvoi_ligne,
gt_create_nomin TYPE TABLE OF zsvoi_ligne,
lv_msg TYPE string,
lt_lines TYPE zsvoi_lines_t,
ls_lines TYPE zsvoi_lines,
lt_lines_2 TYPE zsvoi_indice_t,
ls_lines_2 TYPE zsvoi_indice,
lt_lines_3 TYPE zsvoi_statut_t,
ls_lines_3 TYPE zsvoi_statut,
r_excep TYPE REF TO cx_st_match_element,
it_xml_table TYPE string.
*retrieve the XML data
CALL FUNCTION 'Your_FM'
CHANGING
et_xml_table = it_xml_table.
* Perform the XSLT stylesheet
TRY.
*— Data in the excel will be collected in gs_create_main.
CALL TRANSFORMATION Your_SimpleTransformation
SOURCE XML it_xml_table
RESULT lignes = gs_create_nomin.
APPEND gs_create_nomin TO gt_create_nomin.
CLEAR gs_create_nomin.
CATCH cx_st_match_element INTO r_excep.
lv_msg = r_excep->get_text( ).
WRITE lv_msg.
ENDTRY.
LOOP AT gt_create_nomin INTO gs_create_nomin.
lt_lines = gs_create_nomin-ligne.
LOOP AT lt_lines INTO ls_lines.
lt_lines_2 = ls_lines-indice.
LOOP AT lt_lines_2 INTO ls_lines_2.
lt_lines_3 = ls_lines_2-statut.
LOOP AT lt_lines_3 INTO ls_lines_3.
*insert code to use the data from the internal tables
ENDLOOP.
ENDLOOP.
ENDLOOP.
ENDLOOP.
First, all of the data variables that we use are types of structures we made at the start.
In the CALL FUNCTION replace Your_FM with the FM you just created in SE37.
In CALL TRANSFORMATION replace Your_SimpleTransformation with the simple transformation you created before.
If you go into debug mode you’ll see that gt_create_nomin follows the exact structure of the tables you made at the start, you can fetch all of the data from all of the structures into individual internal tables by looping over them, and in each loop fetching the nested table into a new internal table as you can see in the code. You can then use all these internal tables filled with data to for example fill up a DSO as I did for my project in the empty area I left in the loops. I’m not including the code I used to fill up the DSO because it’s a lot of repetitive code and it’s not optimized yet.
This will conclude my blog on how to fetch data from a deep structure with ABAP.

Sven Swennen
Consultant @ Cubis
