Wednesday, 3 July 2019

ST Transformations: XML 2 ABAP, a working example

Note: this post is not about the differences between XSLT and ST, it’s just a little example for quickly understanding the general structure of a Simple Transformation.

The XML


<?xml version="1.0" encoding="UTF-8"?>
<File>
<Head>
<Name>K. Richards</Name>
</Head>
<Items>
<ITM QTY="23" EAN="123123123123" CAT="BL"/>
<ITM QTY="100" EAN="123123123123" CAT=""/>
<ITM QTY="240" EAN="123123123123" CAT=""/>
<ITM QTY="989" EAN="123123123123" CAT=""/>
<ITM QTY="1000" EAN="123123123123" CAT=""/>
<ITM QTY="5" EAN="123123123123" CAT="BL"/>
<ITM QTY="50" SOH="4000299949" EAN="123123123123" SOI="000010" CAT=""/>
<ITM QTY="140" EAN="123123123123" CAT=""/>
<ITM QTY="420" EAN="123123123123" CAT="QI"/>
<ITM QTY="30" EAN="123123123123" CAT=""/>
<ITM QTY="20" EAN="123123123123" CAT="QI"/>
<ITM QTY="475" SOH="4000299949" EAN="123123123123" SOI="000040" CAT=""/>
<ITM QTY="300" EAN="123123123123" CAT=""/>
<ITM QTY="994" EAN="123123123123" CAT=""/>
<ITM QTY="24" EAN="123123123123" CAT="BL"/>
<ITM QTY="3" EAN="123123123123" CAT="BL"/>
<ITM QTY="441" EAN="123123123123" CAT=""/>
<ITM QTY="240" EAN="123123123123" CAT="QI"/>
<ITM QTY="5" EAN="123123123123" CAT=""/>
<ITM QTY="102" EAN="123123123123" CAT="BL"/>
<ITM QTY="2" EAN="123123123123" CAT=""/>
<ITM QTY="360" EAN="123123123123" CAT="QI"/>
<ITM QTY="403" EAN="123123123123" CAT=""/>
<ITM QTY="425" SOH="123123123123" EAN="6941023243415" SOI="000030" CAT=""/>
<ITM QTY="100" EAN="123123123123" CAT=""/>
<ITM QTY="220" EAN="123123123123" CAT=""/>
<ITM QTY="1000" EAN="123123123123" CAT=""/>
<ITM QTY="25" SOH="4000299949" EAN="123123123123" SOI="000020" CAT="BL"/>
<ITM QTY="425" SOH="4000299949" EAN="123123123123" SOI="000020" CAT=""/>
<ITM QTY="340" EAN="123123123123" CAT=""/>
<ITM QTY="1" EAN="123123123123" CAT="BL"/>
</Items>
</File>

The ST


Code of the ST transformation (transaction STRANS – or directly inside Eclipse ADT):

SAP ABAP Study Materials, SAP ABAP Guides, SAP ABAP Certifications, SAP ABAP Learning

<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates">

  <tt:root name="FILE"/>

  <tt:template>
    <File tt:ref=".FILE"> <!--FILE Needs to match name of RESULT variable in CALL TRANSFORMATION call-->
      <Head tt:ref="HEAD">
        <Name tt:value-ref="NAME"/>
      </Head>
      <Items>
        <tt:loop ref="ITEMS">
          <ITM>
            <tt:group>
              <tt:cond frq="?"><tt:attribute name="QTY" value-ref="QTY"/></tt:cond>
              <tt:cond frq="?"><tt:attribute name="SOH" value-ref="SOH"/></tt:cond>
              <tt:cond frq="?"><tt:attribute name="EAN" value-ref="EAN"/></tt:cond>
              <tt:cond frq="?"><tt:attribute name="SOI" value-ref="SOI"/></tt:cond>
              <tt:cond frq="?"><tt:attribute name="CAT" value-ref="CAT"/></tt:cond>
            </tt:group>
          </ITM>
        </tt:loop>
      </Items>
    </File>
  </tt:template>

</tt:transform>

The ABAP


(almost the same as in the other post, except that I preferred to output the result into a structured variable instead of an internal table, to correspond better to the input XML)

REPORT.

TYPES: BEGIN OF lty_items,
         qty TYPE string,
         soh TYPE string,
         ean TYPE string,
         soi TYPE string,
         cat TYPE string,
       END OF lty_items.

TYPES: BEGIN OF lty_head,
         name TYPE string,
       END OF lty_head.

TYPES: BEGIN OF lty_out,
         head  TYPE lty_head,
         items TYPE STANDARD TABLE OF lty_items WITH DEFAULT KEY,
       END OF lty_out.

DATA: lv_xml TYPE string,
      lt_xml TYPE STANDARD TABLE OF string,
      ls_out TYPE lty_out.

PARAMETERS p_file TYPE string LOWER CASE DEFAULT 'C:\link\to\test.xml'.

"Load xml file
cl_gui_frontend_services=>gui_upload(
  EXPORTING
    filename = p_file
    filetype = 'ASC'
  CHANGING
    data_tab = lt_xml
  EXCEPTIONS
    OTHERS   = 19 ).

lv_xml = concat_lines_of( lt_xml ).

CALL TRANSFORMATION zmy_xslt_2
  SOURCE XML lv_xml
  RESULT file = ls_out.
cl_demo_output=>new( )->write_data( ls_out-head
                     )->write_data( ls_out-items )->display( ).

The result


(running the ABAP program -> contents of variable LS_OUT)

SAP ABAP Study Materials, SAP ABAP Guides, SAP ABAP Certifications, SAP ABAP Learning

Now for some pointers


Here are some important tips

1. ST has a syntax which usually allows the same transformation being called in both directions, from XML to ABAP, but also from ABAP to XML. It’s a great feature, but it also complicates the ST syntax, even if you want to use the transformation only in one direction, especially for optional elements (for instance, tt:group and tt:cond frq=”?” altogether allow the attributes to be optional and in any position)

2. ST is not able to convert from XML to XML (XSLT can do it), but “thanks to that” ST doesn’t require to declare the asXML elements (<asx:abap…; they are required only when you write an XSLT transformation for transforming from or to ABAP).

3. Whatever the direction is, the transformation is always to be written with the XML elements as being elements in the transformation (<element …>), and ABAP component names as being in value-ref and ref attributes (you can see what I mean by comparing the ST and XSLT transformations, they are different although the XSLT writes in the same direction i.e. XML to ABAP).

4. Always respect the case of XML words, it’s very important in all XML languages!

1 comment: