2021 Sep 28 3:45 PM
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
2021 Sep 28 6:13 PM
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>
2021 Sep 28 4:12 PM
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>
2021 Sep 28 6:13 PM
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>
2021 Sep 28 6:28 PM
Great, that's it.
Thank you Sandra!
(still think that "skip" should work with default namespaces and that this is a kernel bug)