Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
kirill_smirnov
Explorer

It sometimes happens... You do not have an SAP PI instance (or something similar), however you need to download (or upload) an XML file, and it is very hard to control the file structure. All you have is an XML schema provided by an external system, and there is a challenge - to re-create in SAP something similar to the file format described in the XSD. And remember - no SAP PI or other Integration Bus capable of doing the import on your behalf!

This tiny utility uses standard SAP ABAP Proxy mechanism to import the data definition and create respective DDIC objects. The process flow is very similar to Service Consumer creation in SPROXY transaction, however with this utility you can use directly use an XSD file (dummy WSDL is created automatically). The utility was also inspired by this blog -  http://sapblog.rmtiwari.com.

Please note that in order to make this post easier to read, I've omitted some basic routines (e.g. for file selection dialogue, message output etc.).

Global data and selection-screen:

*&---------------------------------------------------------------------*
*& Report  Z_IMPORT_XML_SCHEMA
*&
*&---------------------------------------------------------------------*
*& This reports imports an XSD file and calls standard ABAP/4 proxy generation
*& methods to (re-)create DDIC objects
*&---------------------------------------------------------------------*

REPORT  z_import_xml_schema.

TYPE-POOLS: sprx,
             trwbo.
CONSTANTS:
        gc_lcl TYPE packname VALUE '$TMP'.
DATA:
      go_proxy    TYPE REF TO cl_proxy,
      gv_xcontent TYPE xstring,
      gv_wsdl     TYPE xstring.

PARAMETERS:
           p_xsdfn TYPE anyuri OBLIGATORY VALUE CHECK. "XML Schema file name

SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME.
PARAMETERS:
           p_pckg  TYPE packname   VALUE CHECK DEFAULT gc_lcl, " Package
           p_trrq  TYPE trkorr     VALUE CHECK,                " Transport request
           p_prfx  TYPE prx_prefix OBLIGATORY DEFAULT 'Z',     " Prefix
           p_actv  AS CHECKBOX     default 'X'.                " Activate immediately
SELECTION-SCREEN END OF BLOCK b1.

" Transport request selection dialogue:

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_trrq.
   PERFORM get_transport_request CHANGING p_trrq. "

   " File name selection dialogue:

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_xsdfn.
   PERFORM get_file_name CHANGING p_xsdfn. "

I have used the following sequence:

  1. File upload;
  2. Conversion to WSDL - format which is "native" for an ABAP/4 proxy generator;
  3. Instantiation of the proxy object - using a generated WSDL;
  4. DDIC update (and activation if desired);

Step 1 - File upload:

FORM upload_file USING    iv_filename TYPE anyuri
                  CHANGING cv_xcontent TYPE xstring.
   DATA: lo_slib_retriever TYPE REF TO if_slib_retriever,
         lo_exception      TYPE REF TO cx_root,
         lv_fault          TYPE xstring.

   TRY.
       lo_slib_retriever = cl_slib_entity_container=>create_retriever( ).
       cv_xcontent = lo_slib_retriever->get_content( iv_filename  ).
     CATCH cx_slib INTO lo_exception.
       PERFORM output_message USING 'E'
                                    'Unable to read the file specified.'(urf).
       STOP.
   ENDTRY.
ENDFORM.                    "upload_file

Step 2 - WSDL conversion:

FORM xsd2wsdl USING    iv_xcontent TYPE xstring
               CHANGING cv_wsdl     TYPE xstring.

   DATA:
         lv_message   TYPE string,
         lx_gen_error TYPE REF TO cx_proxy_gen_error.

   TRY.
       CALL METHOD cl_proxy_test_utils=>xsd2wsdl
         EXPORTING
           schema = iv_xcontent
         RECEIVING
           wsdl   = cv_wsdl.
     CATCH cx_proxy_gen_error INTO lx_gen_error .
       lv_message = lx_gen_error->if_message~get_text( ).
       PERFORM output_message USING 'E'
                                     lv_message.
       STOP.
   ENDTRY.

ENDFORM.                    "xsd2wsdl

Step 3 - Instantiation of a proxy object:

FORM init_proxy USING     iv_wsdl TYPE xstring
                           iv_pckg
                           iv_praefix
                 CHANGING  co_proxy TYPE REF TO cl_proxy.

   DATA:
        lx_root    TYPE REF TO cx_root,
        lv_message TYPE string.

   TRY.
       CALL METHOD cl_proxy_test_utils=>wsdl2proxy
         EXPORTING
           wsdl    = iv_wsdl
           package = iv_pckg
           praefix = iv_praefix
         RECEIVING
           proxy   = co_proxy.
     CATCH cx_proxy_gen_error INTO lx_root.
       " LX_ROOT is checked below
     CATCH cx_slib INTO lx_root.
       " LX_ROOT is checked below
     CATCH cx_sidl INTO lx_root.
       " LX_ROOT is checked below
   ENDTRY.

   IF lx_root IS BOUND.
     lv_message = lx_root->if_message~get_text( ).
     PERFORM output_message USING 'E'
                                   lv_message.
     STOP.
   ENDIF.

ENDFORM.                    "init_proxy

Step 4 - DDIC update....

FORM save_proxy USING io_proxy TYPE REF TO cl_proxy.
   DATA:
        lx_error   TYPE REF TO cx_proxy_gen_error,
        lv_message TYPE string.

   TRY.
       CALL METHOD io_proxy->save
         CHANGING
           transport_number = p_trrq.
     CATCH cx_proxy_gen_error INTO lx_error .

       lv_message = lx_error->if_message~get_text( ).
       PERFORM output_message USING 'E'
                                     lv_message.
       STOP.

   ENDTRY.

   " No errors:
   PERFORM output_message USING 'S'
                                'Proxy was saved.'(pws).

ENDFORM.                    "save_proxy

....and activation:

FORM activate_proxy USING io_proxy TYPE REF TO cl_proxy
                           iv_trreq TYPE trkorr .
   DATA:
        lt_objects TYPE sprx_log_t,
        lt_log     TYPE sprx_log_t,
        ls_objects LIKE LINE OF lt_objects,
        ls_log     LIKE LINE OF lt_log,
        lx_error   TYPE REF TO cx_proxy_gen_error,
        lv_message TYPE string.


   TRY.
       CALL METHOD io_proxy->activate
         EXPORTING
           activate_all      = 'X'
           deletion          = 'X'
         IMPORTING
           activated_objects = lt_objects
           log               = lt_log
         CHANGING
           transport_number  = iv_trreq.
     CATCH cx_proxy_gen_error INTO lx_error.
       lv_message = lx_error->if_message~get_text( ).
       PERFORM output_message USING 'E'
                                     lv_message.
       STOP.
   ENDTRY.

   IF NOT lt_log[] IS INITIAL.
     PERFORM output_message USING 'I'
                                  'Activation log:'(alo).
     LOOP AT lt_log INTO ls_log.

       MESSAGE ID      ls_log-msgid
               TYPE    ls_log-msgty
               NUMBER  ls_log-msgno
               WITH    ls_log-msgv1
                       ls_log-msgv2
                       ls_log-msgv3
                       ls_log-msgv4
                       INTO lv_message.
       PERFORM output_message USING ls_log-msgty
                                    lv_message.
     ENDLOOP.
   ENDIF.

   IF NOT lt_objects[] IS INITIAL.
     PERFORM output_message USING 'I'
                                'Activated objects:'(oli).
     LOOP AT lt_objects INTO ls_objects.

       MESSAGE ID      ls_objects-msgid
               TYPE    ls_objects-msgty
               NUMBER  ls_objects-msgno
               WITH    ls_objects-msgv1
                       ls_objects-msgv2
                       ls_objects-msgv3
                       ls_objects-msgv4
                       INTO lv_message.
       PERFORM output_message USING ls_objects-msgty
                                    lv_message.
     ENDLOOP.
   ENDIF.

If you prefer not to keep "redundant" development objects, feel free to delete the proxy itself (without deletion of the subsequent objects :smile: ). However, it should affect nothing if the proxy definition is transported to the production environment.

At the end of the day, you will get the DDIC structures which correspond to the ones described in an XML schema. Now using those structures your potential XML Simple Transformations will be really simple.

4 Comments
Labels in this area