Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Trouble using tt:switch / tt:switch-var in simple transformation

bryan_sippel3
Explorer
0 Kudos

Hello gurus,

We are performing a simple transformation on an XML string we retrieve from an external source. A typical sample XML is as follows...

    <VEHICLE ID="2064015">

        <LON>-121.02363</LON>

        <LAT>37.650665</LAT>

        <DATE>2016-05-13 06:53:10.0</DATE>

        <STREETNAME>Lone Palm Ave</STREETNAME>

        <STREETNUM>1127</STREETNUM>

        <LANDMARK>1707 Pacific Supply Modesto</LANDMARK>

        <LANDMARKADDR>1155 North Emerald Ave</LANDMARKADDR>

        <CITY>Modesto</CITY>

        <STATE>CA</STATE>

        <ODOMETER>10466431</ODOMETER>

        <PARAMS>

            <PARAM name="Name">GPS Antenna</PARAM>

            <PARAM name="Status">Connected</PARAM>

        </PARAMS>

    </VEHICLE>

The PARAMS tag can have immediate level tags with the "name" attributes "Name" and "Status" that I would like to transform into my ABAP internal table, but it can alternatively have a nested deep structure that I need to ignore if the associated "name" attribute is "bus".

        <PARAMS>

            <PARAM name="bus">

                <bus>

                    <driver></driver>

                    <trip/>

                    <event>O</event>

                    <eid/>

                    <desc>Active Fault</desc>

                    <data>

                        <datum>

                            <fmi>3</fmi>

                            <desc>Auxiliary Pressure #1-VOLTAGE ABOVE NORMAL, OR SHORTED TO HIGH SOURCE</desc>

                            <oc>126</oc>

                            <spn>1387</spn>

                            <lampstaus>0</lampstaus>

                            <source>49</source>

                        </datum>

                    </data>

                </bus>

            </PARAM>

        </PARAMS>

The SAP documentation describes the tt:switch and tt:switch-var commands, but the examples are a bit lacking.

I have made several attempts using tt:read, tt:attribute, tt:assign, tt:skip, etc, trying to save the attribute value into a variable for testing, but I am still getting the same rather vague error message, "System expected a value for the type C".

<?sap.transform simple?>

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

    <tt:root name="ROOT"/>

    <tt:root name="ROOTPARAMS"/>

    <tt:variable name="PARAMNAME"/>

    <tt:template name="ZVM_XML_TO_TAB">

        <HISTORY>

            <tt:loop name="vehicle" ref=".ROOT">

                <VEHICLE>

                    ...

                    <PARAMS>

                        <tt:loop name="params" ref="$ref.PARAMS">

                            <PARAM>

                                <tt:attribute name="name" ref="var(PARAMNAME)"/>

                                <tt:switch-var>

                                    <tt:cond-var check="var(PARAMNAME) = 'Name' or var(PARAMNAME) = 'Status'">

                                        <tt:attribute name="name" value-ref="var(PARAMNAME)"/>

                                        <tt:value ref="$params.VMPARAMVALUE"/>

                                    </tt:cond-var>

                                    <tt:cond-var>

                                    </tt:cond-var>

                                </tt:switch-var>

                            </PARAM>

                        </tt:loop>

                    </PARAMS>

                    ...

                </VEHICLE>

            </tt:loop>

        </HISTORY>

    </tt:template>

</tt:transform>

Can anyone please tell me what I am doing wrong with the tt:switch-var statement and how it should be corrected?

Essentially, I need to loop through the PARAMS tags, keeping any values where the name attribute is "Name" or "Status" and excluding any values where the name attribute is "bus" and its associated deep structure content.

Thanks,

Bryan

2 REPLIES 2

Sandra_Rossi
Active Contributor
0 Kudos

I can't answer your questions, as ST is not easy to understand. So, you could simplify your ST, transfer all PARAM nodes, and exclude the "bus" node using ABAP.

Program:

types : begin of ty_ls_param,
          paramname  TYPE string,
          paramvalue TYPE string,
        end of ty_ls_param.
data lt_params TYPE TABLE OF ty_ls_param.
data string type string.
concatenate
        '<?xml version="1.0" encoding="UTF-16"?>'
        '<PARAMS>'
        '    <PARAM name="Name">GPS Antenna'
        '    <PARAM name="Status">Connected'
        '    <PARAM name="bus">test bus'
        '</PARAMS>'
into string.
try.
call transformation ztest source xml string result data = lt_params.
data lx_root type ref to cx_root.
catch cx_root into lx_root.
endtry.
DELETE lt_params WHERE paramname = 'bus'. BREAK-POINT.

Transformation "ztest":

<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates"> <tt:root name="DATA"/>
<tt:template>
    <PARAMS>
        <tt:loop ref="DATA">
            <PARAM>
                <tt:attribute name="name" value-ref="PARAMNAME"/>
                <tt:d-cond><bus><tt:skip/></bus></tt:d-cond>
                <tt:value ref="PARAMVALUE"/>
            </PARAM>
        </tt:loop>
    </PARAMS>
</tt:template> </tt:transform>

0 Kudos

The closest transformation I could get for matching yours, is the following:

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

<tt:root name="DATA"/>
<tt:variable name="V_PARAMNAME" type="C" length="10"/>

<tt:template>
    <PARAMS>
        <tt:loop ref="DATA">
            <PARAM>
                <tt:assign to-var="V_PARAMNAME" val="' '"/>
                <tt:attribute name="name">
                    <tt:read var="V_PARAMNAME"/>
                </tt:attribute>
                <tt:switch-var>
                    <tt:cond-var check="var(V_PARAMNAME)='Name'
                                                 or var(V_PARAMNAME)='Status'">
                        <tt:attribute name="name" value-ref="PARAMNAME"/>
                        <tt:value ref="PARAMVALUE"/>
                    </tt:cond-var>
                    <tt:cond-var>
                        <tt:skip/>
                    </tt:cond-var>
                </tt:switch-var>
            </PARAM>
        </tt:loop>
    </PARAMS>
</tt:template>

</tt:transform>

With this transformation, you still get one line in the internal table, but all its components are initial.

Note that your "<tt:attribute name="name" ref="var(PARAMNAME)"/>" always produces an exception as "var(PARAMNAME)" (that you can see while debugging step-by-step the transformation) is not a data node.

I came to the conclusion that it's impossible to skip a line in an internal table during deserialization.

In your case, maybe the best solution is to define one structure for Name and one for Status instead of an internal table.