Tuesday, February 3, 2009

Discovering a Hidden Gem :Generate Simple Transformation for XML in ABAP

Even in its most nascent form, this less known wizard of simple transformation, could be really useful for ABAP developers. I think, ABAP developers would love to have a graphical utility to generate simple transformation/XSLT code.

Almost a year back,  I was writing some happy-code to consume an external web service from ABAP. As the web service was returning the result data in the form of an XML string, I ended up writing a Simple Transformation to get the values in ABAP internal table.

Consuming webservice from ABAP is not the topic of this post but if you need help on this then please check the blogs on SDN. However, If you need to post an answer on a twitter-interview ( similar to a telephonic interview but held on twitter ) then there you go :
Xn SE80->Repository Browser->Enterprise Services->[ right click to bring the context menu ] -->Create Proxy [ use WSDL URL e.g. http://www.webservicex.net/uklocation.asmx?WSDL to generate proxy through wizard ]. Xn LPCONFIG to configure the logical port.

Back to the topic, I spotted this magic-stick in Simple Transformation editor [ Transaction XSLT_TOOL ] and tried to make it work. But could not decipher and wrote the ST manually, instead. Interestingly, I could not find any information  about this so called "Edit Simple Transformation Graphically" feature. In my defence, I searched on SAP OSS, SAP Help & SDN. There you go ...Well search feature on SAP Sites.. is great anyway ;)
A year later, I just happened to be adoring ( developers do this often ) my old code and it reminded me of this utility. I tried figuring out once again and managed to discover something worth sharing.
Service proxy call provides data in the form of XML result. Code for proxy call is as below:

CREATE OBJECT LO_UK_LOCATION.
TRY.
lv_input-POST_CODE = p_post.

CALL METHOD LO_UK_LOCATION->GET_UKLOCATION_BY_POST_CODE
  EXPORTING
    INPUT  = lv_input
  IMPORTING
    OUTPUT = lv_output.

 CATCH CX_AI_SYSTEM_FAULT .
   WRITE : 'CX_AI_SYSTEM_FAULT'.
 CATCH CX_AI_APPLICATION_FAULT .
   WRITE : 'CX_AI_APPLICATION_FAULT'.
ENDTRY.

Now the result variable lv_output will be having the data in the form of an XML string as below.
Tip: You can use a function module SCOL_TRACE_SHOW_XML to show the XML data on screen.
<NewDataSet>
                    <Table>
                              <Town>Balthangie</Town>
                              <County>Aberdeenshire</County>
                              <PostCode>AB53</PostCode>
                     </Table>
                     <Table>
                              <Town>Bankhead</Town>
                              <County>Aberdeenshire</County>
                              <PostCode>AB51</PostCode>
                     </Table>
</NewDataSet>
In order to transform the XML to ABAP internal table, I decided to use Simple Transformation. Now I will generate the simple transformation as below:

  1. Create Table Type ZNEWDATASET in transaction SE11. The hierarchy structure should be compatible with the XML hierarchy.

  2. Now create the ST program in transaction XSLT_TOOL. Spot the magic stick in the editor menu.

  3.  Click on 'Edit Simple Transformation Graphically' button (magic stick) and you will get the editor as below. Create a new root (right click - context menu ) in "Data Roots" section. I've named it NEWDATASET but the important thing is to enter the correct type, created earlier.

  4. Now you can see the data root hierarchy as below. Drag and Drop the NEWDATASET root on right panel ( Simple Transfromation ). It automaically generates the ST nodes corresponding to the ABAP structure. However, you need to adjust the names as per the XML element names.
  5. Now adjust the names in ST panel as per actual XML element names.

  6. Save and Activate. The ST program (Z_TEST), generated by the utility, is as below:
    <?sap.transform simple?>
    <tt:transform xmlns:tt="http://www.sap.com/transformation-templates" xmlns:ddic="http://www.sap.com/abapxml/types/dictionary" xmlns:def="http://www.sap.com/abapxml/types/defined">
        <tt:root name="NEWDATASET" type="ddic:ZNEWDATASET"/>
            <tt:template>
                  <NewDataSet>
                        <tt:loop ref=".NEWDATASET">
                              <Table>
                                         <Town tt:value-ref="TOWN"/>
                                         <County tt:value-ref="COUNTY"/>
                                        <PostCode tt:value-ref="POST_CODE"/>
                              </Table>
                        </tt:loop>
                   </NewDataSet>
             </tt:template>
    </tt:transform>
  7. Now use the code below to get data into ABAP internal table.

    data : result type ZNEWDATASET, "itab of table type ZNEWDATASET
           wa_result like line of result.
    
            call transformation Z_TEST 
              source xml lv_output-GET_UKLOCATION_BY_POST_CODE_R
              result     newdataset = result[].
    
    LOOP AT result into wa_result.
      WRITE :/ wa_result-TOWN, wa_result-COUNTY, wa_result-POST_CODE.
    ENDLOOP.
    
It seems to be a very useful utility. I hope this will be further enhanced by SAP or the SAP Community.
By the way, I checked this on SAP ECC6.0. I will try to explore further for complex XML e.g. elements having attributes.

Please do add your inputs, if you managed to check this out or have done this before.

Updated: 
SAP Help document for ST is at http://help.sap.com/abapdocu/en/ABENABAP_XML.htm
* It's better to Display XML from ABAP as below :
cl_abap_browser=>show_xml( EXPORTING xml_string = xml_string ).

13 comments:

  1. Hello,
    I am studying a couple of blogs, documentations in this topic. All the examples mention this cl_abap_browser class, which doesn't exist in our ECC 6.0 system. Please tell us more information about this class. Thank you.
    Best regards,
    Laszlo.

    ReplyDelete
  2. you can use function SCOL_TRACE_SHOW_XML to show the xml on screen as an alternative. Also, displaying the xml on the screen is generally for test purpose only.

    ReplyDelete
  3. I think class cl_abap_browser is available in ABAP Release 7.1 and not in ABAP 7.0

    ReplyDelete
  4. hi,

    in the xslt_tool i could not find the magic stick. I am getting a dump ST_MATCH_FAIL. I have written ST program similar to the one that you mentioned here. I am getting connected to 'http://209.162.186.60/globalweather.asmx /GetCitiesByCountry?CountryName='

    how to proceed

    ReplyDelete
  5. Hello Ram,
    I am finding your blog on this subject very easy to use. However i am getting the following error message when I attempt your technique " System expected element 'MaterialSchema' ".
    This is a layout sample of the XML we are using for import:

    000000000131201600, Other adhesives and sealantsSEALANT:ADHES,H2,RUBBER,4000000000244122003,BindersBINDER:WITH LABEL HOLDER,11 X 8-2IN

    and this is the generated ST stylesheet code of the transformation:
















    your help is greatly appriciated.

    ReplyDelete
  6. I have a little tricky requirement. I have many XML documents, which I want to merge into 1 XML document with one root that I will define and then download. I found a function module SRTUTIL_CONVERT_XML_TO_TABLE which can convert an XML info to Tag data. I plan to manipulate this tag data and then convert it back to XML. But not able to find how to do that? Any help is appreciated.

    ReplyDelete
  7. Hi there,

    I am not able to check SRTUTIL_CONVERT_XML_TO_TABLE but if you've the data/structure in ABAP then you can create the XML using iXML lib as well.

    see a simple example here :

    for upload and parsing:
    http://passionateaboutsap.com/rmtiwari/Resources/MySolutions/Dev/UtilityCode.html#7

    for creating xml :
    or any iXML related standard function as ref e.g. /ASU/MAP_TAB_TO_XML

    you can also ask for help on SDN : http://sdn.sap.com for quick answers.

    Thanks,
    Ram

    ReplyDelete
  8. Thanks for your blog, really helped. I tried it on nested table and had to removed the extra attribute reference inserted before loop by the wizard.

    ReplyDelete
  9. thnks for this explanation. i need to know how we can generate a st to have xml file with a header and n items.

    ReplyDelete
  10. Hi

    I have a requirement to work with 2 internal tables, one is header table and second one is item table. Once after processing the header line I need to loop the item table to fill the item details. I have tried with several combinations with , but not able to get the expected results. Kindly help me to loop the item table with header reference.

    Thanks
    Praveen

    ReplyDelete
  11. Hi, i had a simple requeriment for transform a two field XML into an abap structure. Your blog guided me succesfully trougth absolute obscurity...
    Really preciated..

    ReplyDelete
  12. Hi Ram,
    I am working on internal table with deep strucure to XML requirement. i.e. my XML document i expect repeating elemnts within top element. I created table types but in the the STRANS, i get the line type of table type as an additional element which i don't want.
    for Ex. if ZTAB is table type with line type as ZLINETYPE having 4 fields as elements, it appears as




    .
    .



    Where as I wanted ... and so on.
    How do i get rid of this additonal element of linetype/strucutre ?
    Am I missing any step ?
    Appreciate your advice.
    BR
    Nilesh

    ReplyDelete
  13. See this post as an example for generating simple transformation from a very complex structure : Prototyping an ABAP OData Entity Data Model Generator .

    You can remove the additional name of the table-type ( that is not required ), by dragging table icon ( just below the table-type-name ) on the table-type-name and then delete the table-type-name node.

    - also it should be easy to just remove not-required table-type/structure-names manually from the generated code.

    ReplyDelete

Info : Comments are reviewed before they are published. SPAMs are rejected.

Copyright