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: 

XML deserialization: error tt:skip and namespaces

UweFetzer_se38
Active Contributor

To ignore some of the incoming XML elements I'm using the <tt:skip> pattern. This works fine like in the following example:

1. Example: don't skip any elements

Transformation template

<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates">
  <tt:root name="ROOT"/>
  <tt:template>
    <data>
      <X1>
        <tt:value ref=".ROOT.COL_A "/>
      </X1>
      <X2>
        <tt:value ref=".ROOT.COL_B "/>
      </X2>
      <X3>
        <tt:value ref=".ROOT.COL_C"/>
      </X3>
    </data>
  </tt:template>
</tt:transform>

Report

    DATA(xml) = |<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n| &
                |<data>\n| &
                |    <X1>aaa</X1>\n| &
                |    <X2>bbb</X2>\n| &
                |    <X3>ccc</X3>\n| &
                |</data>\n|.

    DATA: BEGIN OF result,
            col_a TYPE string,
            col_b TYPE string,
            col_c TYPE string,
          END OF result.

    TRY.
        CALL TRANSFORMATION ztmp_fuw
          SOURCE XML xml
          RESULT root = result.

        cl_demo_output=>display( result ).

      CATCH cx_st_match_text
            cx_st_match_element
            cx_sy_conversion_data_loss
            INTO DATA(lcx).

        cl_demo_output=>display( lcx->get_text( ) ).
    ENDTRY.

Result

COL_A COL_B COL_C 
aaa   bbb   ccc 

2. Example: skip element X2

Transformation template

<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates">
  <tt:root name="ROOT"/>
  <tt:template>
    <data>
      <X1>
        <tt:value ref=".ROOT.COL_A "/>
      </X1>
      <tt:skip name="X2"/>
      <X3>
        <tt:value ref=".ROOT.COL_C"/>
      </X3>
    </data>
  </tt:template>
</tt:transform>

No changes in report.

Result

COL_A COL_B COL_C 
aaa         ccc 

No surprises so far, everything works as expected.

Now we have to process a standarized XML with a namespace in it and the transformation (the skip) doesn't work anymore.

Changed transformation template:

<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates">
  <tt:root name="ROOT"/>
  <tt:template>
    <data xmlns="urn:mynamespace">
      <X1>
        <tt:value ref=".ROOT.COL_A "/>
      </X1>
      <tt:skip name="X2"/>
      <X3>
        <tt:value ref=".ROOT.COL_C"/>
      </X3>
    </data>
  </tt:template>
</tt:transform>

Changed XML in the report:

    DATA(xml) = |<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n| &
                |<data xmlns="urn:mynamespace">\n| &
                |    <X1>aaa</X1>\n| &
                |    <X2>bbb</X2>\n| &
                |    <X3>ccc</X3>\n| &
                |</data>\n|.

Result:

Exception

Element '{urn:mynamespace}X3' expected 

I've tested this behaviour in 7.50 and 7.52, same result.

What am I doing wrong here? Or is it a kernel bug?

Any idea how to use the skip pattern with custom xml namespaces? Or are there any patterns I could use to ignore specific elements - deserialization should work whether they are present or not.

Thank you in advance for your ideas.

Cheers, Uwe

1 ACCEPTED SOLUTION

Sandra_Rossi
Active Contributor

To make all elements optional, you may use tt:extensible="on" or "deep-static" or "deep-dynamic":

<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates">
  <tt:root name="ROOT"/>
  <tt:template>
    <data tt:extensible="deep-dynamic" xmlns="urn:mynamespace">
      <X1>
        <tt:value ref=".ROOT.COL_A "/>
      </X1>
      <X3>
        <tt:value ref=".ROOT.COL_C"/>
      </X3>
    </data>
  </tt:template>
</tt:transform>
3 REPLIES 3

Sandra_Rossi
Active Contributor
0 Kudos

I guess that the skip doesn't work because of missing namespace in name="X2".

You must indicate a namespace prefix before X2 e.g. name="aaaaaaa:X2" with aaaaaaa being any text and xmlns:aaaaaaa="same URI as default namespace" defined in the same node or a node above.

(I don't know how to directly indicate to use the default namespace without using a dummy prefix)

The below code solves your issue:

<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates">
  <tt:root name="ROOT"/>
  <tt:template>
    <data xmlns="urn:mynamespace" xmlns:aaaaaaa="urn:mynamespace">
      <X1>
        <tt:value ref=".ROOT.COL_A "/>
      </X1>
      <tt:skip name="aaaaaaa:X2"/>
      <X3>
        <tt:value ref=".ROOT.COL_C"/>
      </X3>
    </data>
  </tt:template>
</tt:transform>

Sandra_Rossi
Active Contributor

To make all elements optional, you may use tt:extensible="on" or "deep-static" or "deep-dynamic":

<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates">
  <tt:root name="ROOT"/>
  <tt:template>
    <data tt:extensible="deep-dynamic" xmlns="urn:mynamespace">
      <X1>
        <tt:value ref=".ROOT.COL_A "/>
      </X1>
      <X3>
        <tt:value ref=".ROOT.COL_C"/>
      </X3>
    </data>
  </tt:template>
</tt:transform>

Great, that's it.

Thank you Sandra!

(still think that "skip" should work with default namespaces and that this is a kernel bug)