SAP R/3 форум ABAP консультантов
Russian ABAP Developer's Club

Home - FAQ - Search - Memberlist - Usergroups - Profile - Log in to check your private messages - Register - Log in - English
Blogs - Weblogs News

Convert an ABAP table into XML file using SAP DOM Approach



 
Post new topic   Reply to topic    Russian ABAP Developer's Club Forum Index -> Programming Techniques | Приемы программирования -> Conversion
View previous topic :: View next topic  
Author Message
admin
Администратор
Администратор



Joined: 01 Sep 2007
Posts: 1639

PostPosted: Fri Oct 26, 2007 5:10 pm    Post subject: Convert an ABAP table into XML file using SAP DOM Approach Reply with quote

XML DOM Processing in ABAP part I - Convert an ABAP table into XML file using SAP DOM Approach.
Robert Eijpe

Introduction
With NetWeaver 04 SAP introduced simple transformations, a new way of converting XML directly into ABAP tables, structures and fields. Tobias Trapp wrote 5 weblogs about this topic with the title XML processing in ABAP. However the success of these great weblogs, you must have at least a SAP WAS 6.40 environment and you have to learn the Simple Transformation Language. At first another solution was introduced by SAP into the SAP kernel of version 4.6D. This implementation is called the iXML package and could be accessed using and ABAP Object class CL_IXML and about 40 ABAP Object interfaces IF_IXML*. In this weblog I will focus on the possibilities of SAP XML Document Object Model (DOM) processing at the ABAP stack. My objective is to explain how you can use it in abap mapping. For this I split this weblog into three parts. This first part will focus on the conversion of an abap table into an xml file. The second part will focus on the conversion from an xml file (back) to abap tables. The last part will deal with the use of SAP DOM within XI abap mapping, introduced with SAP XI 3.0.

The XML
In this weblog part we will create an xml file on the user’s computer based on data from an SAP system. First we will fill an internal table with SAP data.


Next we will create a document object using an iXML factory. This document can be filled with the data of the internal table. The document object can be represented as a tree structure, the so called Document Object Model or SAP DOM..


After filling the document object, we will transfer it into a XML stream. This stream is the binary version of the XML file and can be represented as a string, an xstring or a table with binary fields.


In the last step we will transfer the XML file to the user’s PC.

The implementation
In this implementation we will only focus on the creation of the XML file and the transfer to the user. You can not create a XML document directly. You have to use a so called ixml factory first.

TYPE-POOLS: ixml.
DATA: l_ixml TYPE REF TO if_ixml.
l_ixml = cl_ixml=>create( ).

This iXML factory can create an empty XML document object named l_document.

DATA: l_document TYPE REF TO if_ixml_document.
l_document = l_ixml->create_document( ).

At this point you can add the nodes (elements, attributes) into the document. First you have to declare the root element node.

DATA: l_element_root TYPE REF TO if_ixml_element.

This node we have to give a name and add it (create_simple_node) to the document object l_document, which will be the parent of this node.

l_element_root = l_document->create_simple_element(
name = 'flights'
parent = l_document ).

Next we can add child nodes to there parent node using the same method of the document object.

DATA: l_element_airline TYPE REF TO if_ixml_element,
l_element_airline = l_document->create_simple_element(
name = 'airline'
parent = l_element_root ).

An attribute can be add easily using the method set_attribute of the element node.

l_rc = l_element_airline->set_attribute( name = 'code' value = 'LH401' ).

Now we have finished the document object. Regretfully it can not be displayed in any form due to the fact that it is a binary object.
The next step is to convert the created document to a flat file. To achieve this we have to create a stream factory, which will help us to create an output stream.

DATA: l_streamfactory TYPE REF TO if_ixml_stream_factory.
l_streamfactory = l_ixml->create_stream_factory( ).

In this case, we will convert the document into an output stream which is based on an internal table of type x.

TYPES: BEGIN OF xml_line,
data(256) TYPE x,
END OF xml_line.
DATA: l_xml_table TYPE TABLE OF xml_line,
l_xml_size TYPE i,
l_rc TYPE i,
l_ostream TYPE REF TO if_ixml_ostream.
l_ostream = l_streamfactory->create_ostream_itable( table = l_xml_table ).

When we have created the output stream we can do the rendering from the document into the stream. The XML data will be stored in the internal table automatically.

DATA: l_renderer TYPE REF TO if_ixml_renderer.
l_renderer = l_ixml->create_renderer( ostream = l_ostream
& nbsp; document = l_document ).
l_rc = l_renderer->render( ).

In the last step we upload the file to the sapgui

l_xml_size = l_ostream->get_num_written_raw( ).

CALL METHOD cl_gui_frontend_services=>gui_download
EXPORTING
bin_filesize = l_xml_size
filename = 'c:\temp\flights.xml'
filetype = 'BIN'
CHANGING
data_tab = l_xml_table
EXCEPTIONS
OTHERS = 24.


This finished the first step-of-three. As mentioned before the next log will focus on the conversion from xml files (back) to abap tables.

A complete example
ABAP Source
Code:
  REPORT  z_xit_xml_dom_create.

  TYPE-POOLS: ixml.

  TYPES: BEGIN OF xml_line,
          data(256) TYPE x,
         END OF xml_line.

  DATA: l_ixml            TYPE REF TO if_ixml,
        l_streamfactory   TYPE REF TO if_ixml_stream_factory,
        l_ostream         TYPE REF TO if_ixml_ostream,
        l_renderer        TYPE REF TO if_ixml_renderer,
        l_document        TYPE REF TO if_ixml_document.

  DATA: l_element_flights TYPE REF TO if_ixml_element,
        l_element_airline TYPE REF TO if_ixml_element,
        l_element_flight  TYPE REF TO if_ixml_element,
        l_element_from    TYPE REF TO if_ixml_element,
        l_element_to      TYPE REF TO if_ixml_element,
        l_element_dummy   TYPE REF TO if_ixml_element,
        l_value           TYPE string.

  DATA: l_xml_table       TYPE TABLE OF xml_line,
        l_xml_size        TYPE i,
        l_rc              TYPE i.

  DATA: lt_spfli          TYPE TABLE OF spfli.
  DATA: l_spfli           TYPE spfli.


  START-OF-SELECTION.
*   Fill the internal table
    SELECT * FROM spfli INTO TABLE lt_spfli.

*   Sort internal table
    SORT lt_spfli BY carrid.

*   Start filling xml dom object from internal table
    LOOP AT lt_spfli INTO l_spfli.

      AT FIRST.
*       Creating a ixml factory
        l_ixml = cl_ixml=>create( ).
*       Creating the dom object model
        l_document = l_ixml->create_document( ).
*       Fill root node with value flights
        l_element_flights  = l_document->create_simple_element(
                    name = 'flights'
                    parent = l_document ).
      ENDAT.

      AT NEW carrid.
*       Create element 'airline' as child of 'flights'
        l_element_airline  = l_document->create_simple_element(
                    name = 'airline'
                    parent = l_element_flights  ).

*       Create attribute 'code' of node 'airline'
        l_value = l_spfli-carrid.
        l_rc = l_element_airline->set_attribute( name = 'code' value = l_value ).

*       Create attribute 'name' of node 'airline'
        SELECT SINGLE carrname FROM scarr INTO l_value WHERE carrid EQ l_spfli-carrid.
        l_rc = l_element_airline->set_attribute( name = 'name' value = l_value ).

      ENDAT.

      AT NEW connid.
*       Create element 'flight' as child of 'airline'
        l_element_flight  = l_document->create_simple_element(
                    name = 'flight'
                    parent = l_element_airline  ).

*       Create attribute 'number' of node 'flight'
        l_value = l_spfli-connid.
        l_rc = l_element_flight->set_attribute( name = 'number' value = l_value ).

      ENDAT.

*     Create element 'from' as child of 'flight'
      CONCATENATE l_spfli-cityfrom ',' l_spfli-countryfr INTO l_value.
      l_element_from  = l_document->create_simple_element(
                  name = 'from'
                  value = l_value
                  parent = l_element_flight  ).

*     Create attribute 'airport' of node 'from'
      l_value = l_spfli-airpfrom.
      l_rc = l_element_from->set_attribute( name = 'airport' value = l_value ).

*     Create element 'to' as child of 'flight'
      CONCATENATE l_spfli-cityto ',' l_spfli-countryto INTO l_value.
      l_element_to  = l_document->create_simple_element(
                  name = 'to'
                  value = l_value
                  parent = l_element_flight  ).

*     Create attribute 'airport' of node 'from'
      l_value = l_spfli-airpto.
      l_rc = l_element_to->set_attribute( name = 'airport' value = l_value ).

*     Create element 'departure' as child of 'flight'
      l_value = l_spfli-deptime.
      l_element_dummy  = l_document->create_simple_element(
                  name = 'departure'
                  value = l_value
                  parent = l_element_flight ).

*     Create element 'arrival' as child of 'flight'
      l_value = l_spfli-arrtime.
      l_element_dummy  = l_document->create_simple_element(
                  name = 'arrival'
                  value = l_value
                  parent = l_element_flight ).

*     Create element 'type' as child of 'flight'
      CASE l_spfli-fltype.
        WHEN 'X'.
          l_value = 'Charter'.
        WHEN OTHERS.
          l_value = 'Scheduled'.
      ENDCASE.
      l_element_dummy  = l_document->create_simple_element(
                  name = 'type'
                  value = l_value
                  parent = l_element_flight ).
    ENDLOOP.
    IF sy-subrc NE 0.
      MESSAGE 'No data into db table ''spfli'', please run program ''SAPBC_DATA_GENERATOR'' with transaction ''SA38''' TYPE 'E'.
    ENDIF.


*   Creating a stream factory
    l_streamfactory = l_ixml->create_stream_factory( ).
*   Connect internal XML table to stream factory
    l_ostream = l_streamfactory->create_ostream_itable( table = l_xml_table ).

*   Rendering the document
    l_renderer = l_ixml->create_renderer( ostream  = l_ostream
                                          document = l_document ).
    l_rc = l_renderer->render( ).

*   Saving the XML document
    l_xml_size = l_ostream->get_num_written_raw( ).

    CALL METHOD cl_gui_frontend_services=>gui_download
      EXPORTING
        bin_filesize = l_xml_size
        filename     = 'c:\temp\flights.xml'
        filetype     = 'BIN'
      CHANGING
        data_tab     = l_xml_table
      EXCEPTIONS
        OTHERS       = 24.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
                 WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.


XML file
Code:
<xml>
<flights>
   <airline>
      <flight>
         <from>NEW YORK,US</from>
         <to>SAN FRANCISCO,US</to>
         <departure>110000</departure>
         <arrival>140100</arrival>
         <type>Scheduled</type>
      </flight>
      <flight>
         <from>SAN FRANCISCO,US</from>
         <to>NEW YORK,US</to>
         <departure>090000</departure>
         <arrival>172100</arrival>
         <type>Scheduled</type>
      </flight>
   </airline>
   <airline>
      <flight>
         <from>ROME,IT</from>
         <to>FRANKFURT,DE</to>
         <departure>190000</departure>
         <arrival>210500</arrival>
         <type>Scheduled</type>
      </flight>
      <flight>
         <from>ROME,IT</from>
         <to>TOKYO,JP</to>
         <departure>120000</departure>
         <arrival>085500</arrival>
         <type>Scheduled</type>
      </flight>
      <flight>
         <from>TOKYO,JP</from>
         <to>ROME,IT</to>
         <departure>114500</departure>
         <arrival>192500</arrival>
         <type>Scheduled</type>
      </flight>
      <flight>
         <from>ROME,IT</from>
         <to>OSAKA,JP</to>
         <departure>103500</departure>
         <arrival>081000</arrival>
         <type>Charter</type>
      </flight>
   </airline>
   <airline>
      <flight>
         <from>SAN FRANCISCO,US</from>
         <to>NEW YORK,US</to>
         <departure>100000</departure>
         <arrival>182500</arrival>
         <type>Scheduled</type>
      </flight>
      <flight>
         <from>NEW YORK,US</from>
         <to>SAN FRANCISCO,US</to>
         <departure>171500</departure>
         <arrival>203700</arrival>
         <type>Scheduled</type>
      </flight>
      <flight>
         <from>NEW YORK,US</from>
         <to>FRANKFURT,DE</to>
         <departure>193500</departure>
         <arrival>093000</arrival>
         <type>Scheduled</type>
      </flight>
   </airline>
   <airline>
      <flight>
         <from>TOKYO,JP</from>
         <to>FRANKFURT,DE</to>
         <departure>133000</departure>
         <arrival>173500</arrival>
         <type>Scheduled</type>
      </flight>
      <flight>
         <from>FRANKFURT,DE</from>
         <to>TOKYO,JP</to>
         <departure>202500</departure>
         <arrival>154000</arrival>
         <type>Charter</type>
      </flight>
   </airline>
   <airline>
      <flight>
         <from>BERLIN,DE</from>
         <to>FRANKFURT,DE</to>
         <departure>071000</departure>
         <arrival>081500</arrival>
         <type>Scheduled</type>
      </flight>
      <flight>
         <from>FRANKFURT,DE</from>
         <to>BERLIN,DE</to>
         <departure>103000</departure>
         <arrival>113500</arrival>
         <type>Scheduled</type>
      </flight>
      <flight>
         <from>FRANKFURT,DE</from>
         <to>NEW YORK,US</to>
         <departure>133000</departure>
         <arrival>150500</arrival>
         <type>Charter</type>
      </flight>
      <flight>
         <from>NEW YORK,US</from>
         <to>FRANKFURT,DE</to>
         <departure>183000</departure>
         <arrival>074500</arrival>
         <type>Scheduled</type>
      </flight>
      <flight>
         <from>FRANKFURT,DE</from>
         <to>NEW YORK,US</to>
         <departure>101000</departure>
         <arrival>113400</arrival>
         <type>Scheduled</type>
      </flight>
   </airline>
   <airline>
      <flight>
         <from>SINGAPORE,SG</from>
         <to>FRANKFURT,DE</to>
         <departure>225000</departure>
         <arrival>053500</arrival>
         <type>Scheduled</type>
      </flight>
      <flight>
         <from>FRANKFURT,DE</from>
         <to>SINGAPORE,SG</to>
         <departure>205500</departure>
         <arrival>150500</arrival>
         <type>Scheduled</type>
      </flight>
   </airline>
   <airline>
      <flight>
         <from>SINGAPORE,SG</from>
         <to>TOKYO,JP</to>
         <departure>163500</departure>
         <arrival>001500</arrival>
         <type>Scheduled</type>
      </flight>
      <flight>
         <from>SINGAPORE,SG</from>
         <to>JAKARTA,ID</to>
         <departure>152500</departure>
         <arrival>160000</arrival>
         <type>Scheduled</type>
      </flight>
      <flight>
         <from>SAN FRANCISCO,US</from>
         <to>SINGAPORE,SG</to>
         <departure>160000</departure>
         <arrival>024500</arrival>
         <type>Scheduled</type>
      </flight>
      <flight>
         <from>SINGAPORE,SG</from>
         <to>SAN FRANCISCO,US</to>
         <departure>170000</departure>
         <arrival>192500</arrival>
         <type>Scheduled</type>
      </flight>
   </airline>
   <airline>
      <flight>
         <from>FRANKFURT,DE</from>
         <to>SAN FRANCISCO,US</to>
         <departure>143000</departure>
         <arrival>170600</arrival>
         <type>Scheduled</type>
      </flight>
      <flight>
         <from>SAN FRANCISCO,US</from>
         <to>FRANKFURT,DE</to>
         <departure>150000</departure>
         <arrival>103000</arrival>
         <type>Scheduled</type>
      </flight>
      <flight>
         <from>NEW YORK,US</from>
         <to>FRANKFURT,DE</to>
         <departure>162000</departure>
         <arrival>054500</arrival>
         <type>Scheduled</type>
      </flight>
      <flight>
         <from>FRANKFURT,DE</from>
         <to>NEW YORK,US</to>
         <departure>104000</departure>
         <arrival>125500</arrival>
         <type>Scheduled</type>
      </flight>
   </airline>
</flights>


https://www.sdn.sap.com/irj/sdn/weblogs?blog=/pub/wlg/2657
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Russian ABAP Developer's Club Forum Index -> Programming Techniques | Приемы программирования -> Conversion All times are GMT + 4 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


All product names are trademarks of their respective companies. SAPNET.RU websites are in no way affiliated with SAP AG.
SAP, SAP R/3, R/3 software, mySAP, ABAP, BAPI, xApps, SAP NetWeaver and any other are registered trademarks of SAP AG.
Every effort is made to ensure content integrity. Use information on this site at your own risk.