
To be able, during deserialization, to react to variable XML inbound streams that contain groups of related elements in any sequence, you can combine conditional transformations in a group, which can be processed more than once during deserialization. To do this, you use the tt:group statement:
<tt:group>
case1
case2
</tt:group>
In tt:group , you can specify a list of cases case1 , case2 , ... Syntactically, every case case1 , case2 , ... is formulated by a conditional transformation , that is, a subelement tt:[s-|d-]cond . In this case, tt:[s-]cond defines a serialization-relevant case, and tt:[d-]cond a deserialization-relevant case. Other direct subelements are not possible in tt:group . The statement tt:group can be a subelement of tt:[s-|d-]cond .
In contrast to conditional transformations positioned outside of tt:group , there is no need to specify at least one attribute using , data or check for a case, provided that the content of tt:[s-|d-]cond is not a pattern .
Note the following in the list of cases case1 , case2 , ...:
You may specify any number of serialization-relevant cases in which no attribute (using, data, or check) is specified.
You may specify only one deserialization-relevant case that does not contain a pattern . This case is called standard deserialization.
To control how often a deserialization-relevant case must or can be executed during deserialization, tt:[d-]cond within tt:group can contain the additional attribute frq (frequency) with one of three allowed values:
< /tt:[d-]cond ... frq="1" >
Required case. The case must be executed exactly once while the group is processed.
< /tt:[d-]cond ... frq="?" >
Optional case. The case is executed up to once while the group is processed.
< /tt:[d-]cond ... frq="*" >
Multiple case. The case can be executed any number of times while the group is processed.
For frq="?" and frq="*" , the expected element must not necessarily exist in the XML inbound stream.
Implicit frequency: If the attribute frq is not specified explicitly,
frq="1" is used implicitly in tt:cond cases that do not contain data conditions (that must be executed during serialization).
frq="?" is used implicitly in tt:cond cases that contain a data condition (that need not be executed during serialization).
Serialization
During serialization, the element tt:group is executed once as follows:
All serialization-relevant cases with fulfilled prerequisite or no prerequisite using , data , or check are executed in the given order.
Deserialization
During deserialization, the element tt:group initiates a loop. The system tries to select every required case (frequency 1 ) once. As soon as this happens, the loop ends. Until then, optional cases (frequency ? , up to once) and multiple cases (frequency * , also multiple) can also be selected. In every loop pass, one of the deserialization-relevant cases whose maximum case frequency has not yet been reached is selected as follows:
The first case that contains a suitable pattern is executed (deserialization and assertions met).
If no such case exists, the system tries to execute the standard deserialization, if it exists. If the possible prerequisites using , data , or check of the standard deserialization are not met, the exception CX_ST_REF_ACCESS is raised.
If no standard deserialization exists, the exception CX_ST_GROUP_MISSING_CASE is raised.
Example
The following transformation shows how groupings work:
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates">
<tt:root name="ROOT1"/>
<tt:root name="ROOT2"/>
<tt:root name="ROOT3"/>
<tt:root name="ROOT4"/>
<tt:template>
<X0>
<tt:group>
<tt:cond>
<X3>
<tt:value ref="ROOT3"/>
</X3>
</tt:cond>
<tt:cond frq="?">
<X2>
<tt:value ref="ROOT2"/>
</X2>
</tt:cond>
<tt:cond frq="*">
<X1>
<tt:value ref="ROOT1"/>
</X1>
</tt:cond>
<tt:cond>
<tt:skip count="1"/>
</tt:cond>
</tt:group>
<X4>
<tt:value ref="ROOT4"/>
</X4>
</X0>
</tt:template>
</tt:transform>
Assume that an XML inbound stream has the following form:
<X0>
<X1>1</X1>
<X1>2</X1>
<X2>3</X2>
<X2>4</X2>
<X3>5</X3>
<X4>6</X4>
</X0>
The deserialization proceeds as follows:
In the first loop pass, element X1 is used and the first element X1 deserialized; ROOT1 is set to 1.
In the second loop pass, element X1 is used again because of condition tt:cond frq="*" and the second element X1 deserialized; ROOT1 is set to 2.
In the third loop pass, element X2 is used and the first element X2 deserialized; ROOT2 is set to 3.
In the fourth loop pass, element X2 cannot be used again because of condition tt:cond frq="?" . Instead, the second element X2 is skipped in the standard deserialization with tt:skip . Specifying count is necessary because otherwise all subsequent elements would be skipped.
In the fifth loop pass, element X3 is used and the first element X3 deserialized; ROOT3 is set to 5.
All required cases of the group have been selected, so the loop ends. Element X4 is deserialized outside of tt:group ; ROOT4 is set to 6.