Sunday, April 5, 2009

Generate Simple Transformation for XML in ABAP - Part II

Just wanted to quickly add some more information to my last post on the same topic "Discovering a Hidden Gem :Generate Simple Transformation for XML in ABAP"

In this example, I will show how to use  "Edit Simple Transformation Graphically" feature of XSLT_TOOL to generate simple transformations for XML elements having attributes.

Let's say there is a requirement to generate XML document from the ABAP data/ internal tables. And the resultant XML document should have the following structure. Basically, POST_CODE should be an attribute of "Town" element. 
<?xml version="1.0" encoding="utf-8" ?>

<NewDataset>
   <Table>
      <Town POST_CODE="B5">BIRMINGHAM</Town>
      <County>WARWICK</County>
  </Table>
<Table>
      <Town POST_CODE="NP20">NEWPORT</Town>
      <County>WALES</County>
</Table>
</NewDataset>
Initial steps are similar to the example in my last post [ so I've just copied the screen shots from there ]
  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. Delete the PostCode element as we need this as an attribute of Town, rather than an element.




  6. Important thing to remember: Always use 'SAVE' before adding , deleting or modifying nodes. Otherwise you will face errors during node operations.
  7. Select node "Town", and then click on "First Child" button at the top toolbar. Further, use right click to get the conext menu for "Town" element and create a new attribute 'POST_CODE". Now drag the POST_CODE from left panel (data) to right panel on the POST_CODE attribute to create association. The index numbers shows the association between data nodes and xml nodes.


Save and Activate. The ST program (Z_RAM_TEST_ATTR1), 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:attribute name="POST_CODE" value-ref="$REF.POST_CODE"/>
                                                      <tt:value ref="TOWN"/>
                                               </Town>
                                     <County tt:value-ref="COUNTY"/>
                          </Table>
                    </tt:loop>
               </NewDataSet>
         </tt:template>
</tt:transform>
Example ABAP code to call the transformation is as below:
REPORT  z_ram_abap_to_xml.

DATA : lt_source TYPE znewdataset,
       wa_source LIKE LINE OF lt_source,
       xml_result TYPE xstring.  "xstring ensures UTF-8 encoding

wa_source-town = 'BIRMINGHAM'.
wa_source-county = 'WARWICK'.
wa_source-post_code = 'B5'.
APPEND wa_source TO lt_source.

wa_source-town = 'NEWPORT'.
wa_source-county = 'WALES'.
wa_source-post_code = 'NP20'.
APPEND wa_source TO lt_source.

CALL TRANSFORMATION z_ram_test_attr1
  SOURCE newdataset = lt_source[]
  RESULT XML  xml_result  .

CALL FUNCTION 'SCOL_TRACE_SHOW_XML'
  EXPORTING
    xdoc = xml_result.


In case you want  help on how to download the XML documents etc, please check the standard example transaction SSTDEMO1

29 comments:

  1. I like the fact that its straight forward to follow and even though you did put in bold red "Always use 'SAVE' before adding" - some of us forget! lol

    ReplyDelete
  2. Excellent explanation...I was googling to know XML in SAP ABAP. This article clarified my doubts. Keep writing all the good stuff.

    Regards,

    ReplyDelete
  3. Beautiful blog...this is what exactly i was looking for .......

    ReplyDelete
  4. It works great. After activating ST I decided to add another field in my structure. I have activated the structure and the table type.

    How to reflect the new field in my ST?

    ReplyDelete
  5. It Is A Great Work

    ReplyDelete
  6. GĂ©nial ! Even for a french developper !

    ReplyDelete
  7. Can this be done in SAP 4.7? If not, any manual methods to go around with the steps?

    ReplyDelete
  8. In 4.7, you can use XSLT or iXML library instead of ST ( simple transformation).

    - iXML example http://passionateaboutsap.com/rmtiwari/Resources/MySolutions/Dev/UtilityCode.html#7

    - XSLT [ http://help.sap.com/saphelp_nw04/helpdata/en/a8/824c3c66177414e10000000a114084/frameset.htm ]

    If you need quick response, I would suggest to ask such questions in forums like http://sdn.sap.com .

    Thanks,
    Ram

    ReplyDelete
    Replies
    1. First link needs authentification user/pw (for what?)
      Second link is broken (as so often with sap.com)

      Delete
  9. How to change the tag, mean to say suppose i want to have the tag like ".

    ReplyDelete
  10. Thanks for this step by step explanation on how to generate simple transformation for xml in ABAP. It helped me a lot

    ReplyDelete
  11. Hi,
    how can you set or change the encoding?

    ReplyDelete
  12. For changing XML encoding, try this one below :

    It's using xstream so I guess we don't need to change the content encoding. Only the XML header encoding change is required.
    Now ST seems to output UTF-8 encoding only. Hence I am cheating a bit by using standard XSLT ID to convert XML to XML as post-processing & in the process setting the encoding as required.

    REPORT z_test_ram_xml.

    * complex structure example
    DATA : lt_itab TYPE ldapaltab,
    wa_itab LIKE LINE OF lt_itab ,
    lt_val TYPE valtabc,
    wa_val LIKE LINE OF lt_val .

    DATA: gv_xml_xstring TYPE xstring.
    DATA: gv_final_xml_xstring TYPE xstring.

    * <<< Populate Example data in complex struture itab
    wa_itab-name = 'header1'.
    wa_itab-typ = 'header2'.
    wa_itab-operation = 'header3'.

    wa_val-val = 'Hi'.
    APPEND wa_val TO wa_itab-vals.
    wa_val-val = 'How r you'.
    APPEND wa_val TO wa_itab-vals.

    APPEND wa_itab TO lt_itab.
    *>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    * This is the main ST call.
    CALL TRANSFORMATION z_test_ram
    SOURCE ldap_table = lt_itab[]
    RESULT XML gv_xml_xstring.
    *>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    * Now a Bit of cheating - to get the encoding we'll use standard XSLT ID
    * rather than ST - not required if you need Default UTF-8 from ST

    DATA :go_ixml TYPE REF TO if_ixml,
    go_stream_factory TYPE REF TO if_ixml_stream_factory,
    go_encoding TYPE REF TO if_ixml_encoding,
    go_resstream TYPE REF TO if_ixml_ostream.

    CONSTANTS: gc_encoding TYPE string VALUE 'UTF-16'. "or UTF-8 etc.

    go_ixml = cl_ixml=>create( ).
    go_stream_factory = go_ixml->create_stream_factory( ).
    go_encoding = go_ixml->create_encoding( character_set = gc_encoding byte_order = 0 ).
    go_resstream = go_stream_factory->create_ostream_XSTRING( gv_final_xml_xstring ).

    CALL METHOD go_resstream->set_encoding( go_encoding ).

    CALL TRANSFORMATION ID
    SOURCE XML gv_xml_xstring
    RESULT XML go_resstream.

    cl_salv_data_services=>download_xml_to_file(
    filename = 'C:\z_test_ram_xml_file.xml'
    xcontent = gv_final_xml_xstring ).


    *-----------------------
    If you need the ST Z_TEST_RAM is again generated through the tool as below:

    ReplyDelete
  13. Hi,

    I would like to keep in my defined namespaces such as in my output file:



    But when I call transformation xml output doesn't have any defined namespace. For example:


    This is the output:




    12345678

    WARWICK

    cccc
    xxxxxxx


    99999999

    PACO

    DDDD
    AAAA



    And I would like to have something like:




    12345678

    WARWICK

    cccc
    xxxxxxx


    99999999

    PACO

    DDDD
    AAAA



    Where node defined namespace is still in the xml file. How can I get this?

    Thanks.

    ReplyDelete
    Replies
    1. Seems like your xml code did not come through in the comment as it does not accept the code..in any case, please check the 2nd example in sap help link regarding namespace in ST.

      <tt:namespace name="abc" />

      http://help.sap.com/saphelp_nwpi71/helpdata/en/63/6a20401fe52402e10000000a1550b0/content.htm

      Delete
  14. Hi,

    I need to generate an XML of format .

    A 1 2 3
    2 2 2
    3 3 3
    B 1 1 1
    2 2 2
    C 3 3 3

    So I created a Deep Structure Table type with table type Inside.

    But when i am Calling the transformation in program it throwing an error in german.
    Simple Transformations transformieren nur von ABAP nach XML und umgekehrt.

    Kindly help

    ReplyDelete
  15. Very useful blog. I want to remove the header . Is it possible through IXML way?

    ReplyDelete
  16. This comment has been removed by the author.

    ReplyDelete
  17. See latest post on how to automatically generate Simple Transformation for a given XML/XSD. Power of the Core : Using XSD for XML Transformation in ABAP

    ReplyDelete
    Replies
    1. Hi Ram,
      Is their a way we can have these xml tags generated as a mix and match of upper case and lower case when downloaded from SAP..To give you an example :

      Addtional attributes


      Delete
  18. Hi to everyone.

    We have an implementation in my job that needs to hide fields on an xml transformation.
    Is there any way to change an additional attribute of a field to hide it?

    Regards
    MatĂ­as

    ReplyDelete
  19. Great work, thank you

    ReplyDelete
  20. Do you know if we can customize the format of the date/time? My requirement is not YYYY-MM-DD and DD/MM/YYYY.
    Thank you in advance.

    ReplyDelete
    Replies
    1. Did you get any solution,I have the same requirement.
      Thanks in advance.

      Delete
  21. Hello Ram,

    The example is very informative , thanks for such a nice documentation. But in the report program the function 'SCOL_TRACE_SHOW_XML' is not described any where . Could you plesas describe the function.

    With Regards,
    Jawahir Kashim

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

    ReplyDelete
  23. Hello,

    Thanks for this blog; very useful and handy

    I need to produce an XML for a vendor that has many invoices with many items. The xml should be like this:











    How should I proceed. I have been able to get the following. I am unable to group the items under the same invoice. Thanks for your helps.

    -
    -
    10001
    -
    001
    000010



    -
    -
    10001
    -
    001
    000020


    ReplyDelete
  24. XML code did not come through in the comment so not really sure but ..as mentioned in my previous comment :
    -------------------
    See this post as an example for generating simple transformation for a complex structure : Prototyping an ABAP OData Entity Data Model Generator . Basically you'll need to create the ABAP deep-structure as per the XML hierarchy that you want to generate.

    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
  25. Hi,

    I am trying to generate a ST for converting XML data into ABAP. For simple data, we are able to create the ST and use it for XML to ABAP and vice versa. But in case the XML has 1000 tags and we need just 300 tags out of it, is it possible to create an ST for this transformation.
    Currently when we try to create an ST for a smaller XML and if we miss out any fields in it, the transformation gives an error during processing with the message expecting 'xxxxx' field.
    Is there a way to avoid having to create a complex hierarchical ABAP Structure with 1000 fields when we need only 300 fields out of the xml?

    ReplyDelete

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

Copyright