Showing posts with label XML. Show all posts
Showing posts with label XML. Show all posts

Jun 13, 2012

Conversion of IDOC to XML format


By Suresh Parvathaneni and Narasimha Motupalli

This Tutorial details about the step by step in conversion of IDOCs to XML format for further use in XI or any other application. It is assumed that the reader of this Tutorial has some knowledge in ALE, IDOCs and Change Pointers.

Scenario
Conversion of the Material IDOC (Message type: MATMAS) to XML format and store the same in the application server of SAP®.

Approach
Change pointers are used for sending IDOCs for master data like Material Master. To work with Change pointers, following two steps have to be performed:
  • Turn on change pointer update generally
  • Providing the message types to be included for change pointer updation.
 To do the above configurations:
TCode: SALE --> IDOC Interface / Application Link Enabling (SALE) --> Modeling and implementing Business Processes --> Master Data Distribution  --> Replication of Master Data
ALE Configuration Steps:
  1. Creation of logical system for the sender system.
  2. Assignment of logical system to the client.
  3. Create a logical system for the recipient
  4. Creation of RFC destination (Connection type:TCP/IP)
  
  1.  Creation of Model View (TCode: BD64).
  1. Save the Model View and Generate Partner Profiles.
  2. There might be a problem with the automatic Port creation. Creation of the port has to be done manually.
  3. Create an XML Port from the transaction WE21 (Port type: XML File).
Here directory is the path on the application server. The Function Module is used for file naming conventions. Any of the SAP® provided function modules could be used for this (Use F4 help to check on this) or create any custom function module for any other naming conventions.
In the outbound trigger tab, mention the RFC destination created earlier.
  
  1. Make an entry in the partner profile generated earlier for message type MATMAS.
  1. A background job need to be scheduled, for a periodic run (interval as required) for the program RBDMIDOC with the message type MATMAS.
  2. Depending on the settings in the partner profiles, it may be necessary to send IDocs directly by executing the program RSEOUT00 (if the setting is to “Collect IDocs”)
Test the above scenario by creating a material using MM01. An XML file would have been created in the directory specified in the XML port. The file could be downloaded onto the front-end system using the transaction CG3Y.



Aug 24, 2011

How To Get The Records from the XML File

How To Get The Records from the XML File

Use these routines to get data/ records from XML

 

PERFORM f_parse_file USING wv_pifile
                    CHANGING wt_xml_table
                             wt_errdata .
*READ DATA FROM TEMPORARY INTERNAL TABLE TO FINAL STRUCTURE
PERFORM f_create_file USING wt_xml_table
                       CHANGING wa_liste_evt  .


*&---------------------------------------------------------------------*
*&      Form  F_PARSE_FILE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->FPU_PIFILE      text
*      -->FPC_WT_XML      text
*      -->FPC_WT_ERRDATA  text
*----------------------------------------------------------------------*
FORM f_parse_file    USING fpu_pifile TYPE string
                  CHANGING fpc_wt_xml TYPE tt_xml_table
                           fpc_wt_errdata TYPE tt_errdata.

  DATA: lo_pixml          TYPE REF TO if_ixml,
        lo_pdocument      TYPE REF TO if_ixml_document,
        lo_pstreamfactory TYPE REF TO if_ixml_stream_factory,
        lo_pistream       TYPE REF TO if_ixml_istream,
        lo_pparser        TYPE REF TO if_ixml_parser,
        lo_pnode          TYPE REF TO if_ixml_node,
        lo_pparseerror    TYPE REF TO if_ixml_parse_error,
        wlv_string        TYPE string,
        wlv_count         TYPE i,
        wlv_index         TYPE i,
        wlv_totalsize     TYPE i,
        wlt_xml_c         TYPE STANDARD TABLE OF t_xml_c,
        wlt_xml_x         TYPE STANDARD TABLE OF t_xml_x,
        wlv_xstring       TYPE xstring,
        wla_errdata       TYPE t_errdata.

*READ PHYSICAL FILE TO AN INTERNAL TABLE
  PERFORM f_read_file USING fpu_pifile
                   CHANGING wlt_xml_c .
*CONVERT TEXT TO XSTRING FORMAT
  IF NOT wlt_xml_c IS INITIAL.
    CALL FUNCTION 'SCMS_TEXT_TO_XSTRING'
      IMPORTING
        buffer   = wlv_xstring
      TABLES
        text_tab = wlt_xml_c
      EXCEPTIONS
        failed   = 1.

    IF sy-subrc <> 0.
      MESSAGE e030 WITH p_file.
    ENDIF.

  ELSE.
    MESSAGE e020 WITH p_file.
  ENDIF.
*Convert xstring to binary
  CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
    EXPORTING
      buffer        = wlv_xstring
    IMPORTING
      output_length = wlv_totalsize
    TABLES
      binary_tab    = wlt_xml_x.
*-- CREATE THE MAIN FACTORY
  lo_pixml = cl_ixml=>create( ).

*-- CREATE THE INITIAL DOCUMENT
  lo_pdocument = lo_pixml->create_document( ).

*-- CREATE THE STREAM FACTORY
  lo_pstreamfactory = lo_pixml->create_stream_factory( ).

*-- CREATE AN INPUT STREAM FOR THE TABLE
  lo_pistream = lo_pstreamfactory->create_istream_itable( table =
  wlt_xml_x
                                                          size  =
                                                          wlv_totalsize
                                                          ).
*-- CREATE THE PARSER
  lo_pparser = lo_pixml->create_parser( stream_factory =
  lo_pstreamfactory
                                        istream        = lo_pistream
                                        document       = lo_pdocument ).
*-- PARSE THE STREAM
  IF lo_pparser->parse( ) NE 0.
*Error handling for parser object
    IF lo_pparser->num_errors( ) NE 0.
      wlv_count = lo_pparser->num_errors( ).
      wlv_index = 0.
      WHILE wlv_index < wlv_count.
        lo_pparseerror = lo_pparser->get_error( index = wlv_index ).
        wlv_string = lo_pparseerror->get_reason( ).
        TRANSLATE wlv_string TO UPPER CASE.
*Gets the error description updated in the Error table
        CONCATENATE text-001 wc_colon wlv_string INTO wla_errdata-value.
        wla_errdata-typ = wc_err.
        APPEND wla_errdata TO fpc_wt_errdata.  CLEAR wla_errdata.
        wlv_index = wlv_index + 1.
      ENDWHILE.
    ENDIF.
  ENDIF.
*-- THE STREAM IS NO LONGER NEEDED, SO CLOSE IT...
  CALL METHOD lo_pistream->close( ).
  CLEAR lo_pistream.

*IF COUNT > 0 THEN THE XML FILE HAD TROUBLES LIKE INCOMPLETE TAGS,
*MISSING PARTS, ETC.
  IF wlv_count > 0.
    EXIT.
  ENDIF.
*-- PUT THE WHOLE DOM TREE AS A LIST...
  lo_pnode = lo_pdocument.
*  GETS THE TYPE AND VALUE OF EACH NODE OF THE DOCUMENT
  PERFORM f_fill_table USING lo_pnode
                   CHANGING fpc_wt_xml .

  FREE : wlt_xml_c, wlt_xml_x.
ENDFORM.                    " F_READ_FILE
*&---------------------------------------------------------------------*
*&      FORM  F_FILL_TABLE
*&---------------------------------------------------------------------*
*  GETS THE TYPE AND VALUE OF EACH NODE OF THE DOCUMENT
*----------------------------------------------------------------------*
*   -->FPU_WL_PNODE     NODE
*   <--FPC_WT_XML_TABLE OUTPUT TABLE WITH ALL THE NODES IN TABULAR FORM
*----------------------------------------------------------------------*
FORM f_fill_table   USING value(fpu_wl_pnode) TYPE REF TO if_ixml_node
                 CHANGING fpc_wt_xml_table    TYPE tt_xml_table.

* LOCAL DECLARATIONS
  DATA: wla_xml_wa     TYPE t_xml_list,
        wlv_ptext      TYPE REF TO if_ixml_text,
        wlv_name       TYPE string,
        wlv_value      TYPE string.

*THIS CODE CHECKS SERIALLY EACH NODE FOR ITS TYPE AND APPENDS IN THE
*COLUMN
*ELEMENT NAME OR ELEMENT VALUE ACCORDINGLY.
  CASE fpu_wl_pnode->get_type( ).
    WHEN if_ixml_node=>co_node_element.
      wlv_name = fpu_wl_pnode->get_name( ).

*HERE COMES THE FIELD NAME FROM THE XML FILE
      wla_xml_wa-name = wlv_name.

      TRANSLATE wla_xml_wa-name TO UPPER CASE.
*INSERT ALL FIELDS FROM XML INTO AN INTERNAL TABLE
      APPEND wla_xml_wa TO fpc_wt_xml_table.
      CLEAR wla_xml_wa.

    WHEN if_ixml_node=>co_node_text.
      wlv_ptext ?= fpu_wl_pnode->query_interface( ixml_iid_text ).
      IF wlv_ptext->ws_only( ) IS INITIAL.
*HERE COMES THE FIELD VALUE
        wlv_value = fpu_wl_pnode->get_value( ).
        wla_xml_wa-value = wlv_value.
        MODIFY fpc_wt_xml_table FROM wla_xml_wa
                           INDEX sy-tabix
                    TRANSPORTING value.
        CLEAR wla_xml_wa.
      ENDIF.
    WHEN OTHERS .
*Do nothing.
  ENDCASE.

  fpu_wl_pnode = fpu_wl_pnode->get_first_child( ).

  WHILE NOT fpu_wl_pnode IS INITIAL.

    PERFORM f_fill_table USING fpu_wl_pnode
                      CHANGING fpc_wt_xml_table .

    fpu_wl_pnode = fpu_wl_pnode->get_next( ).

  ENDWHILE.
ENDFORM.                    " F_FILL_NODE


*&---------------------------------------------------------------------*
*&      Form  F_CREATE_FILE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->FPU_WT_XML_TABLE  text
*      -->FPC_WA_LISTE_EVT  text
*----------------------------------------------------------------------*
FORM f_create_file  USING fpu_wt_xml_table TYPE tt_xml_table
                 CHANGING fpc_wa_liste_evt TYPE t_wa_liste_evt.

  FIELD-SYMBOLS : <f_fieldname>  TYPE ANY,
                  <f_value>  TYPE ANY,
                  <wa>  TYPE ANY.
  DATA : wlv_fieldname  TYPE char15,
         wlv_fieldvalue TYPE char20,
         wlv_count      TYPE i VALUE 1,
         wla_xml_wa     TYPE t_xml_list,
         wla_psl        TYPE t_wa_psl ,
         wla_evt        TYPE t_evt.

  DATA : BEGIN OF wlt_psl,
          psl TYPE tt_psl,
         END OF wlt_psl.

  LOOP AT fpu_wt_xml_table INTO wla_xml_wa FROM 3.
*THIS CODE WILL FILL THE WA FOR LEVEL 2 DATA OF TECH SPECS
    IF wla_xml_wa-name = wc_flg_typ    OR
       wla_xml_wa-name = wc_cod_soc    OR
       wla_xml_wa-name = wc_num_uat_tc OR
       wla_xml_wa-name = wc_dat_etd    OR
       wla_xml_wa-name = wc_num_evt.

      wlv_fieldname = wla_xml_wa-name.
      wlv_fieldvalue = wla_xml_wa-value.
      CONDENSE wlv_fieldname.
      ASSIGN wlv_fieldname TO <f_fieldname>.
      ASSIGN wlv_fieldvalue TO <f_value>.
      ASSIGN COMPONENT <f_fieldname> OF STRUCTURE wla_evt TO <wa>.
      <wa> = <f_value>.

      UNASSIGN : <wa>, <f_fieldname>, <f_value>.
      CLEAR : wlv_fieldname, wlv_fieldvalue .

    ELSEIF
*THIS CODE WILL FILL THE LEVEL 5 DATA OF THE TECH SPECS
       wla_xml_wa-name = wc_num_ord     OR
       wla_xml_wa-name = wc_cod_psl     OR
       wla_xml_wa-name = wc_lib_psl     OR
       wla_xml_wa-name = wc_cod_pro     OR
       wla_xml_wa-name = wc_cod_sta     OR
       wla_xml_wa-name = wc_dat_prv     OR
       wla_xml_wa-name = wc_dat_prv_rea OR
       wla_xml_wa-name = wc_dat_eff     OR
       wla_xml_wa-name = wc_dat_cre     OR
       wla_xml_wa-name = wc_com1        OR
       wla_xml_wa-name = wc_flg_ale     OR
       wla_xml_wa-name = wc_cod_inct    OR
       wla_xml_wa-name = wc_cod_vil     OR
       wla_xml_wa-name = wc_cod_trs     OR
       wla_xml_wa-name = wc_cod_trs_mlt_stp .

* ASSIGN FIELD NAME TO FIELD SYMBOL
      wlv_fieldname = wla_xml_wa-name.
* ASSIGN FIELD VALUE TO FIELD SYMBOL
      wlv_fieldvalue = wla_xml_wa-value.

      CONDENSE wlv_fieldname.
*USE FIELD SYMBOLS TO FILL THE VALUES FROM
*WL_XML_WA TO STRUCTURE WA_LISTE_EVT
      ASSIGN wlv_fieldname TO <f_fieldname>.
      ASSIGN wlv_fieldvalue TO <f_value>.
      ASSIGN COMPONENT <f_fieldname> OF STRUCTURE wla_psl TO <wa>.
      <wa> = <f_value>.
*APPEND LINE OF WA_PSL TO TABLE WT_PSL-PSL
      IF wlv_fieldname = wc_cod_trs_mlt_stp.
        APPEND wla_psl TO wlt_psl-psl.
        CLEAR wla_psl.
*COUNTER TO SURPASS THE FIRST OCCURENCE OF FIELDNAME 'EVT'
        wlv_count = wlv_count + 1.
      ENDIF.
      UNASSIGN : <wa>, <f_fieldname>, <f_value>.
      CLEAR : wlv_fieldname, wlv_fieldvalue .
    ELSEIF
* TO APPEND ALL THE PSL ITEMS FOR SINGLE LINE OF EVT
* WLV_COUNT <> 1 MEANS OCCURENCE OF NEW DATA FOR LEVEL2 OF TS
      wla_xml_wa-name = wc_evt AND wlv_count <> 1.
      APPEND LINES OF wlt_psl-psl TO wla_evt-liste_psl-psl.
      APPEND wla_evt TO fpc_wa_liste_evt-liste_evt-evt.
      CLEAR : wlt_psl-psl[], wla_evt .
    ENDIF.
  ENDLOOP.

* TO APPEND THE LAST RECORD TO LEVEL 2 AND LEVEL 4 OF TS
  APPEND LINES OF wlt_psl-psl TO wla_evt-liste_psl-psl.
  APPEND wla_evt TO fpc_wa_liste_evt-liste_evt-evt.
  CLEAR wla_evt .

  FREE : wlt_psl-psl[].

ENDFORM.                    " F_CREATE_FILE