Skip to Content

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 🙂 ). 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.

To report this post you need to login first.

4 Comments

You must be Logged on to comment or reply to a post.

  1. Vlad Rinciog

    Hello,

     

    Can you provide the entire code?

     

    For example, the missing performs:

     

    PERFORM get_transport_request CHANGING p_trrq.  PERFORM get_file_name CHANGING p_xsdfn. ”

    PERFORM get_file_name CHANGING p_xsdfn.

     

    and  maybe what is missing?

     

    I need this for:

     

    I’m working on a request for Poland to make an adjustment for a legal requirement. I installed an OSS note and made all the customizing and now we are facing problems with the XML. I know that the XML is the full responsibility of the customer, but maybe someone has an idea how can we create an XML to export the date from the 3 tables. (This requirement contain 3 tables(FIPLD_VAT_I, FIPLD_VAT_H, and FIPLD_VA_SUM) generated by the note and fulfilled by the report RPFIPL_SAFT with extraction). The idea is that on the official website with legal requirement we received a schema for JPK_VAT and it’s XSD format. I need somehow to upload that schema into sap and fulfill it with data from those tables and export in XML.
    Thanks in advance,

    Vlad

     

    (0) 
  2. Former Member

    Hello everyone,

    As Kirill, I have the same situation, that is, no SAP PI, no SOAMANAGER.

    I have the XSD file and if I understood corretly, the program mentioned generate DDIC from XDS file.

    The Kirill text say about the dummy WSDL(is created automatically). I folow all the steps but, after execute de program I receive the message: –> Invalid URL xmldsig-core-schema.xsd <– In XSD file line 3 (below) there is a call to a schemaLocation=”./xmldsig-core-schema.xsd”/. This file is stored at the same directory.

    I am not sure, but in debug mode I saw some access to Kernel Method to obtain the URL. My intention is not  involve basis, but only create a DDIC with all structure table thru a ABAP program.

    Does anyone achieved sucess in this hard work.

    Thanks in advance.

     

    Below, the tiny file XSD to generate DDIC in SAP.

    <?xml version="1.0" encoding="utf-8"?>
    <xs:schema xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.reinf.esocial.gov.br/schemas/evtInfoContribuinte/v1_03_00" targetNamespace="http://www.reinf.esocial.gov.br/schemas/evtInfoContribuinte/v1_03_00" elementFormDefault="qualified" attributeFormDefault="unqualified">
      <xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="./xmldsig-core-schema.xsd"/>
      <xs:element name="Reinf">
        <xs:annotation>
          <xs:documentation>EFD-Reinf</xs:documentation>
        </xs:annotation>
        <xs:complexType>
          <xs:sequence>

     

    Valter.

    (0) 
  3. Former Member

    Hello all, first, thanks Kirill for your code! I imported this code and added the missing portions from other SAP standard code, here it is, use at own risk. For me it generated quite a number of DDIC structures from the XSD we have received. I have yet to see if it created all the ones needed. Use $TMP package initially to not impact an existing package or dev class. Also for me it did not save on transport probably because I used $TMP initially, and also got a proxy generation error. But it appears the proxy itself can be removed and not transported if needed.

    *&———————————————————————*
    *& 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 TITLE text-001.
    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.

    * Create 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.

    START-OF-SELECTION.

    PERFORM upload_file USING p_xsdfn
    CHANGING gv_xcontent.

    PERFORM xsd2wsdl USING gv_xcontent
    CHANGING gv_wsdl.

    PERFORM init_proxy USING gv_wsdl
    p_pckg
    p_prfx
    CHANGING go_proxy.

    PERFORM save_proxy USING go_proxy.

    IF NOT p_actv IS INITIAL.
    PERFORM activate_proxy USING go_proxy
    p_trrq.
    ENDIF.

    END-OF-SELECTION.

    *&———————————————————————*
    *& Form upload_file
    *&———————————————————————*
    * text
    *———————————————————————-*
    * –>IV_FILENAME text
    * –>CV_XCONTENT text
    *———————————————————————-*
    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

    *&———————————————————————*
    *& Form xsd2wsdl
    *&———————————————————————*
    * text
    *———————————————————————-*
    * –>IV_XCONTENT text
    * –>CV_WSDL text
    *———————————————————————-*
    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

    *&———————————————————————*
    *& Form init_proxy
    *&———————————————————————*
    * text
    *———————————————————————-*
    * –>IV_WSDL text
    * –>IV_PCKG text
    * –>IV_PRAEFIX text
    * –>CO_PROXY text
    *———————————————————————-*
    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

    *&———————————————————————*
    *& Form save_proxy
    *&———————————————————————*
    * text
    *———————————————————————-*
    * –>IO_PROXY text
    *———————————————————————-*
    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

    *&———————————————————————*
    *& Form activate_proxy
    *&———————————————————————*
    * text
    *———————————————————————-*
    * –>IO_PROXY text
    * –>IV_TRREQ text
    *———————————————————————-*
    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.
    ENDFORM. “activate_proxy
    *&———————————————————————*
    *& Form OUTPUT_MESSAGE
    *&———————————————————————*
    * text
    *———————————————————————-*
    * –>P_0116 text
    * –>P_0117 text
    *———————————————————————-*
    FORM output_message USING i_msg
    i_text.
    WRITE : / i_msg, i_text.

    ENDFORM. ” OUTPUT_MESSAGE
    *&———————————————————————*
    *& Form GET_FILE_NAME
    *&———————————————————————*
    * text
    *———————————————————————-*
    * <–P_P_XSDFN text
    *———————————————————————-*
    FORM get_file_name CHANGING filename.

    DATA:
    l_rc TYPE i,
    l_action TYPE i,
    l_file_table TYPE filetable,
    l_file TYPE LINE OF filetable,
    l_title TYPE string.

    l_title = ‘File name'(001).

    CALL METHOD cl_gui_frontend_services=>file_open_dialog
    EXPORTING
    window_title = l_title
    multiselection = space
    CHANGING
    file_table = l_file_table
    rc = l_rc
    user_action = l_action
    EXCEPTIONS
    file_open_dialog_failed = 1
    cntl_error = 2
    error_no_gui = 3
    not_supported_by_gui = 4
    OTHERS = 5.

    IF sy-subrc = 0 AND l_rc = 1 AND l_action = cl_gui_frontend_services=>action_ok.
    READ TABLE l_file_table INDEX 1 INTO l_file.
    filename = l_file-filename.
    ENDIF.

    ENDFORM. ” GET_FILE_NAME
    *&———————————————————————*
    *& Form GET_TRANSPORT_REQUEST
    *&———————————————————————*
    * text
    *———————————————————————-*
    * <–transport text
    *———————————————————————-*
    FORM get_transport_request CHANGING transport.

    DATA: lv_len TYPE n,
    lv_trfunction LIKE e070-trfunction,
    ls_user TYPE trwbo_user,
    lt_users TYPE trwbo_users,
    ls_new_request TYPE trwbo_request_header.

    CALL FUNCTION ‘TR_POPUP_SELECT_REQUEST_TYPE’
    EXPORTING
    iv_trfunctions = ‘KWTCEO’ “all transport types
    iv_title = ‘Create transport’
    IMPORTING
    ev_trfunction = lv_trfunction
    EXCEPTIONS
    action_aborted_by_user = 1.
    IF sy-subrc <> 0.
    PERFORM send_current_message USING ‘S’.
    EXIT.
    ENDIF.

    IF lv_trfunction CA ‘KW’.
    ls_user-user = sy-uname.
    APPEND ls_user TO lt_users.
    ENDIF.

    CALL FUNCTION ‘TR_REQUEST_MODIFY’
    EXPORTING
    iv_action = ‘CREA’
    iv_new_request_type = lv_trfunction
    it_users = lt_users
    IMPORTING
    es_new_request = ls_new_request
    EXCEPTIONS
    OTHERS = 1.
    IF sy-subrc <> 0.
    PERFORM send_current_message USING ‘S’.
    EXIT.
    ENDIF.

    transport = ls_new_request-trkorr.

    CALL FUNCTION ‘TR_PRESENT_REQUEST’
    EXPORTING
    iv_trkorr = ls_new_request-trkorr.

    ENDFORM. ” GET_TRANSPORT_REQUEST
    *&———————————————————————*
    *& Form SEND_CURRENT_MESSAGE
    *&———————————————————————*
    * text
    *———————————————————————-*
    * –>pv_mstyp text
    *———————————————————————-*
    FORM send_current_message USING value(pv_mstyp) LIKE sy-msgty.
    MESSAGE ID sy-msgid
    TYPE pv_mstyp
    NUMBER sy-msgno
    WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDFORM. ” SEND_CURRENT_MESSAGE

    (0) 

Leave a Reply