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: 

How to deal with empty tags in simple transformations

Hi,

I am facing and issue when trying to de-serialize an xml file. The file contains elements which might or might not have content:

<copyright>
This is some copyright text
<copyrightDetails>
Some details
</copyrightDetails>
</copyright>

or

<copyright>
<copyrightDetails>
Some details
</copyrightDetails>
</copyright>

When processing the following simple transformation, it fails in the second case:

<copyright>
<tt:value ref="$ref.copyright"/>
<copyrightDetails>
<tt:value ref="$ref.copyrightDetails"/>
</copyrightDetails>
</copyright>

How can this be managed?

9 REPLIES 9

Sandra_Rossi
Active Contributor

Good question, I'm also wondering. Whatever I do, I get the error "System expected a value for the type g" at the line <tt:value ref="DATA.COPYRIGHT"/>...

  METHOD abap_unit.
    TYPES: BEGIN OF ty_transfo_result,
            COPYRIGHT        TYPE string,
            COPYRIGHTDETAILS TYPE string,
           END OF ty_transfo_result.
    transfo_name = create_transfo( concat_lines_of( sep = |\r\n| table = VALUE string_table(
              ( `<?sap.transform simple?>                               ` )
              ( `<tt:transform                                          ` )
              ( `xmlns:tt="http://www.sap.com/transformation-templates">` )
              ( `  <tt:root name="DATA"/>                               ` )
              ( `                                                       ` )
              ( `  <tt:template>                                        ` )
              ( `    <copyright>                                        ` )
              ( `         <tt:value ref="DATA.COPYRIGHT"/>              ` )
              ( `         <copyrightDetails>                            ` )
              ( `              <tt:value ref="DATA.COPYRIGHTDETAILS"/>  ` )
              ( `         </copyrightDetails>                           ` )
              ( `    </copyright>                                       ` )
              ( `  </tt:template>                                       ` )
              ( `                                                       ` )
              ( `</tt:transform>                                        ` ) ) ) ).
    DATA(transfo_result) = VALUE ty_transfo_result( ).
    DATA(xml) ='<copyright>'
*            && '     This is some copyright text'
            && '     <copyrightDetails>'
            && '          Some details'
            && '     </copyrightDetails>'
            && '</copyright>'.
    CALL TRANSFORMATION (transfo_name)
        SOURCE XML xml
        RESULT DATA = transfo_result.
    cl_abap_unit_assert=>assert_equals(
        act = transfo_result
        exp = VALUE ty_transfo_result(
*            COPYRIGHT        = `     This is some copyright text     `
            COPYRIGHTDETAILS = `          Some details     ` ) ).
  ENDMETHOD.

0 Kudos

sandra.rossi

Many thanks for your quick reply. It is strange for me to see how simple transformations fail to deal with seemingly easy and apparently trivial XML matters...

0 Kudos

Please use the COMMENT button for comments, asking for complements, adding details, replying to a comment or a proposed solution or to the OP question, etc., ANSWER is only to propose a solution, dixit SAP text at the right of the answer area.

lenapadeken
Product and Topic Expert
Product and Topic Expert

Hi imro_dev1,

If you have elements with optional content in your XML file, you have to work with conditions. ST expects exactly what you define, so in your case, content is expected.

Best regards,

Lena

0 Kudos

Do you know how to make the conditions work as there's no "pattern" for the condition? I tried the classic <tt:cond> but couldn't make it work due to a missing pattern.

stefan_bresch
Employee
Employee

Hi Sandra,

you need to additionally group the conditions:

  <tt:template>
    <copyright>
      <tt:group>
        <tt:cond frq="?">
          <tt:value ref="DATA.COPYRIGHT"/>
        </tt:cond>
        <tt:cond frq="1">
          <copyrightDetails>
            <tt:value ref="DATA.COPYRIGHTDETAILS"/>
          </copyrightDetails>
        </tt:cond>
      </tt:group>
    </copyright>
  </tt:template>

This template shall work for both examples.

Best Regards
Stefan

Nice, it works, thanks!

TYPES: BEGIN OF ty_transfo_result,
             copyright        TYPE string,
             copyrightdetails TYPE string,
           END OF ty_transfo_result.
    DATA transfo_result TYPE ty_transfo_result.
ENDCLASS.
CLASS ltc_test IMPLEMENTATION.
  METHOD create_transfo.
        result = lcl_r3tr_xtra=>create_update_r3tr_xtra_object(
            i_transfo_prefix = i_transfo_prefix
            i_xslt_source    = concat_lines_of( sep   = |\r\n|
                                                table = VALUE string_table(
                                                    ( `<?sap.transform simple?>                               ` )
                                                    ( `<tt:transform                                          ` )
                                                    ( `xmlns:tt="http://www.sap.com/transformation-templates">` )
                                                    ( `  <tt:root name="DATA"/>                               ` )
                                                    ( `                                                       ` )
                                                    ( `  <tt:template>                                        ` )
                                                    ( `    <copyright>                                        ` )
                                                    ( `      <tt:group>                                       ` )
                                                    ( `        <tt:cond frq="?">                              ` )
                                                    ( `          <tt:value ref="DATA.COPYRIGHT"/>             ` )
                                                    ( `        </tt:cond>                                     ` )
                                                    ( `        <tt:cond frq="1">                              ` )
                                                    ( `          <copyrightDetails>                           ` )
                                                    ( `            <tt:value ref="DATA.COPYRIGHTDETAILS"/>    ` )
                                                    ( `          </copyrightDetails>                          ` )
                                                    ( `        </tt:cond>                                     ` )
                                                    ( `      </tt:group>                                      ` )
                                                    ( `    </copyright>                                       ` )
                                                    ( `  </tt:template>                                       ` )
                                                    ( `                                                       ` )
                                                    ( `</tt:transform>                                        ` ) ) ) && |\r\n| ).
  ENDMETHOD.

  METHOD test1.
    transfo_name = create_transfo( ).
    DATA(xml) ='<copyright>'
            && '     <copyrightDetails>'
            && '          Some details'
            && '     </copyrightDetails>'
            && '</copyright>'.
    CALL TRANSFORMATION (transfo_name)
         SOURCE XML xml
         RESULT data = transfo_result.
    cl_abap_unit_assert=>assert_equals( 
              act = transfo_result

        exp = VALUE ty_transfo_result( copyrightdetails = `          Some details     ` ) ).

  ENDMETHOD.

  METHOD test2.
    transfo_name = create_transfo( ).
    DATA(xml) ='<copyright>'
            && '     This is some copyright text'
            && '     <copyrightDetails>'
            && '          Some details'
            && '     </copyrightDetails>'
            && '</copyright>'.
    CALL TRANSFORMATION (transfo_name)
         SOURCE XML xml
         RESULT data = transfo_result.
    cl_abap_unit_assert=>assert_equals( 
        act = transfo_result

        exp = VALUE ty_transfo_result( copyright        = `     This is some copyright text     `
                                       copyrightdetails = `          Some details     ` ) ).
  ENDMETHOD.
ENDCLASS. 

0 Kudos

stefan.bresch

Many thanks, Stefan, it worked!

Quick question: what would be the value of 'frq' for 0 to many entries?

Based on the documentation, the following applies:

  • frq="1" - execute (element expected) exactly once;
  • frq="?" - execute (element optional) none or up to once;
  • frq="*" - execute (element expected) multiple times.

None of these seem to cover the 0 to many case. Would for that the straight <tt:cond> be used?

Cheers,

Ferenc

lenapadeken
Product and Topic Expert
Product and Topic Expert

Hi Ferenc,

0 to many should be included in frq="*": If you read further in the documentation it says "For frq="?" and frq="*", the expected element must not necessarily exist in the inbound XML stream."

Best regards,

Lena