ETSI's Bug Tracker - Part 09: Using XML with TTCN-3
View Issue Details

ID | Project | Category | View Status | Date Submitted | Last Update
0005852 | Part 09: Using XML with TTCN-3 | Technical | public | 22-12-2010 12:27 | 13-07-2011 16:33

Reporter | Jacob Wieland - Spirent |
Assigned To | Gyorgy Rethy |
Priority | high | Severity | minor | Reproducibility | have not tried
Status | closed | Resolution | fixed |
Platform |  | OS |  | OS Version |
Product Version |  |
Target Version |  | Fixed in Version |  |
Clause Reference(s) | XSD Language Mapping, section 7.1.4
For STF discussion |
Source (company - Author) | Testing Technologies - Jacob Wieland

Summary | 0005852: choice with optional content should be mapped to an optional union field

Description

The special case that one element (or sub-particle) of a choice particle can occur 0 times (minOccurs="0") should be handled in the way that the resulting union field in the TTCN-3 type should be optional.
Otherwise, if more than one alternative is 'optional', it is unclear which alternative shall be chosen if none of the elements allowed in the choice are present in the XML.
Example:
<choice>
<element name="a" minOccurs="0" type="A_Type"/>
<element name="b" minOccurs="0" maxOccurs="10" type="B_Type"/>
</choice>
should be mapped to a field like:
union {
A_Type a,
record length (1 .. 10) of B_Type b
} choice optional
Of course, this is true for any sub-particle of a choice which describes the empty XML element concatenation.
Basically, the rule should be: if one of the sub-fields of a union should be optional in regard to minOccurs or can be the empty list, the union should be optional instead.

Steps To Reproduce |
Additional Information |
Tags | No tags attached.
Relationships |
Attached Files | CR5852_resolution_v1.doc (157,184) 01-07-2011 10:14 http://oldforge.etsi.org/mantis/file_download.php?file_id=2543&type=bug CR5852_resolution_v2.doc (75,776) 01-07-2011 16:44 http://oldforge.etsi.org/mantis/file_download.php?file_id=2553&type=bug

Issue History
Date Modified | Username | Field | Change
22-12-2010 12:27 | Jacob Wieland - Spirent | New Issue |
22-12-2010 12:27 | Jacob Wieland - Spirent | Clause Reference(s) | => XSD Language Mapping, section 7.1.4
22-12-2010 12:27 | Jacob Wieland - Spirent | Source (company - Author) | => Testing Technologies - Jacob Wieland
24-05-2011 15:05 | Gyorgy Rethy | Note Added: 0010026 |
24-05-2011 15:05 | Gyorgy Rethy | Assigned To | => Gyorgy Rethy
24-05-2011 15:05 | Gyorgy Rethy | Status | new => assigned
24-05-2011 15:05 | Gyorgy Rethy | Target Version | => Edition 4.3.2 (interim)
24-05-2011 19:22 | Gyorgy Rethy | Priority | normal => high
25-05-2011 16:58 | Gyorgy Rethy | Note Edited: 0010026 |
02-06-2011 14:44 | Gyorgy Rethy | Note Added: 0010112 |
02-06-2011 14:52 | Gyorgy Rethy | Note Edited: 0010112 |
02-06-2011 15:16 | Gyorgy Rethy | Note Edited: 0010112 |
02-06-2011 15:40 | Gyorgy Rethy | Note Edited: 0010112 |
06-06-2011 12:04 | Jacob Wieland - Spirent | Note Added: 0010113 |
30-06-2011 12:16 | Gyorgy Rethy | Note Edited: 0010112 |
30-06-2011 12:53 | Gyorgy Rethy | Note Added: 0010156 |
30-06-2011 14:39 | Gyorgy Rethy | Note Added: 0010158 |
01-07-2011 10:14 | Gyorgy Rethy | File Added: CR5852_resolution_v1.doc |
01-07-2011 10:15 | Gyorgy Rethy | Note Added: 0010172 |
01-07-2011 10:16 | Gyorgy Rethy | Assigned To | Gyorgy Rethy => Ina Schieferdecker
01-07-2011 14:03 | Gyorgy Rethy | Assigned To | Ina Schieferdecker => Jacob Wieland - Spirent
01-07-2011 16:44 | Jacob Wieland - Spirent | File Added: CR5852_resolution_v2.doc |
01-07-2011 16:44 | Jacob Wieland - Spirent | Note Added: 0010189 |
01-07-2011 16:44 | Jacob Wieland - Spirent | Assigned To | Jacob Wieland - Spirent => Gyorgy Rethy
01-07-2011 16:58 | Gyorgy Rethy | Status | assigned => resolved
01-07-2011 16:58 | Gyorgy Rethy | Resolution | open => fixed
13-07-2011 16:33 | Gyorgy Rethy | Status | resolved => closed
13-07-2011 16:33 | Gyorgy Rethy | Note Added: 0010219 |
13-07-2011 16:33 | Gyorgy Rethy | Fixed in Version | => Edition 4.3.2 (interim)

Notes

(0010026)
Gyorgy Rethy
24-05-2011 15:05 (edited on: 25-05-2011 16:58)

3GPP related CR. Check the possible solution.

(0010112)
Gyorgy Rethy
02-06-2011 14:44 (edited on: 30-06-2011 12:16)

Yes, this seems to be an unhandled case... though the case when more than one alternative has minOccurs="0" should be a rather specific one, supposedly used very rarely, as doesn't make much technical sense.
To understand it better, we have to look at the possible cases when choice can appear:
1) as a complexType on its own
2) as a choice group
===========================================
As compositor of complexTypes, e.g.
<complexType name="e25choOptional">
<choice>
<element name="title" type="string" minOccurs="0"/>
<element name="forename" type="string" minOccurs="0"/>
<element name="surname" type="string" minOccurs="0"/>
</choice>
</complexType>
<element name="elemChoOptional" type="ns:e25choOptional"/>
This could be handled in two ways:
-----------------------------
1.a)
As proposed above:
type record E25choOptional {
union {
XSD.String title,
XSD.String forename,
XSD.String surname
} choice optional
}
with {
variant "name as uncapitalized";
variant (choice) "untagged";
};
type E25choOptional ElemChoOptional
with {
variant "name as uncapitalized";
variant "element";
};
template ElemChoOptional t_ElemChoOptional := { choice := omit }
-----------------------------
1.b) In this case translating minOccurs="0" maxOccurs="1" to a record of:
type record E25choOptional {
union {
record length(0 .. 1) of XSD.String title_list,
record length(0 .. 1) of XSD.String forename_list,
record length(0 .. 1) of XSD.String surname_list
} choice
}
with {
variant "name as uncapitalized";
variant (choice) "untagged";
variant (choice.title_list) "untagged";
variant (choice.title_list[-]) "name as 'title'";
variant (choice.forename_list) "untagged";
variant (choice.forename_list[-]) "name as 'forename'";
variant (choice.surname_list) "untagged";
variant (choice.surname_list[-]) "name as 'surname'";
};
type E25choOptional ElemChoOptional
with {
variant "name as uncapitalized";
variant "element";
};
template ElemChoOptional t_ElemChoOptional := { choice := {title_list := {}}}
In this case, of course, there also shall be the same rule as for union-s, the first matching alternative "wins", thus receiving an empty element would be decoded to:
{ choice := { title_list := { } } }
Not nice, but can work
===========================================
Let see these two options also in the case, when choice is used as a governor of groups, embedded in another choice group:
For example:
<group name="e25ChoGroupOpt">
<choice>
<element name="title" type="string" minOccurs="0"/>
<element name="forename" type="string" minOccurs="0"/>
<element name="surname" type="string" minOccurs="0"/>
</choice>
</group>
<group name="e25ChoChoGroupOpt">
<choice>
<group ref="ns:e25ChoGroupOpt"/>
</choice>
</group>
<element name="elemFromChoGroupOpt">
<complexType>
<group ref="ns:e25ChoChoGroupOpt"/>
</complexType>
</element>
-----------------------------
2.a) translated according to the proposal to:
type union E25ChoGroupOpt {
XSD.String title,
XSD.String forename,
XSD.String surname
}
with {
variant "untagged";
};
type union E25ChoChoGroupOpt {
E25ChoGroupOpt e25ChoGroupOpt
}
with {
variant "untagged";
};
type record ElemFromChoGroupOpt {
E25ChoChoGroupOpt e25ChoChoGroupOpt optional
}
with {
variant "name as uncapitalized";
variant "element";
};
template ElemFromChoGroupOpt t_ElemFromChoGroupOpt := { e25ChoChoGroupOpt := omit }
-----------------------------
2.b) or with the modified min/maxOccurs conversion to:
type union E25ChoGroupOpt {
record length(0 .. 1) of XSD.String title_list,
record length(0 .. 1) of XSD.String forename_list,
record length(0 .. 1) of XSD.String surname_list
}
with {
variant "untagged";
variant (choice.title_list) "untagged";
variant (choice.title_list[-]) "name as 'title'";
variant (choice.forename_list) "untagged";
variant (choice.forename_list[-]) "name as 'forename'";
variant (choice.surname_list) "untagged";
variant (choice.surname_list[-]) "name as 'surname'";
};
type union E25ChoChoGroupOpt {
E25ChoGroupOpt e25ChoGroupOpt
}
with {
variant "untagged";
};
type record ElemChoFromGroupOptional {
E25ChoChoGroupOpt e25ChoChoGroupOpt
}
with {
variant "name as uncapitalized";
variant "element";
};
template ElemFromChoGroupOptional t_ElemFromChoGroupOptional := {e25ChoChoGroupOpt:= {e25ChoGroupOpt := {title_list :={}}}}
===========================================
Let see these two options in the case, when the groups is embedded in a sequence group:
<!-- e25ChoGroupOpt as above -->
<group name="e25SeqChoGroupOpt">
<sequence>
<group ref="ns:e25ChoGroupOpt"/>
</sequence>
</group>
<element name="elemFromSeqGroupOpt">
<complexType>
<group ref="ns:e25SeqChoGroupOpt"/>
</complexType>
</element>
-----------------------------
3.a) According to the proposed solution:
type record E25SeqChoGroupOpt {
E25ChoGroupOpt e25ChoGroupOpt optional
}
with {
variant "untagged";
};
type record ElemFromSeqGroupOpt {
E25SeqChoGroupOpt e25SeqChoGroupOpt
}
with {
variant "name as uncapitalized";
variant "element";
};
template ElemFromSeqGroupOpt t_ElemFromSeqGroupOpt := { e25SeqChoGroupOpt:= {e25ChoGroupOpt:=omit }}
-----------------------------
3.b) or with the modified min/maxOccurs conversion to:
type record E25SeqChoGroupOpt {
E25ChoGroupOpt e25ChoGroupOpt
}
with {
variant "untagged";
};
type record ElemFromSeqGroupOpt {
E25SeqChoGroupOpt e25SeqChoGroupOpt
}
with {
variant "name as uncapitalized";
variant "element";
};
template ElemFromSeqGroupOpt t_ElemFromSeqGroupOpt := {e25SeqChoGroupOpt:= {e25ChoGroupOpt := {title_list :={}}}}
===========================================
So, to sum up the experince from the above trial is:
- if using the proposed solution:
the respective union itself cannot be always made optional but all occurances shall be made optional where the given union is USED in a record the first time. Therefore, for example, no template resulting an empty element can be written for the types E25ChoGroupOpt, E25ChoChoGroupOpt. The values/templates using the type are simpler, but depending on the USE, fields at different levels shall be omitted.
This would be dificult to handle in the standard (changes at more places).
- if using the modified min/maxOccurs mapping:
The minOccurs="0" is handled directly at the place where it is used. The values/templates are more complex, but consistent in all cases (value has to be discased to the depth of the respective union in all cases, independent of the use of the union.). At matching, this case is more tricky as the user shall remember that in case of an empty element the decoder picks the first alternative. To implement it in the standard, it would need an additional one-two sentence(s) in clause 7.1.4 ("MinOccurs and maxOccurs"), exactly the place where the user would search for the rule.
Taking into account the findings of the above "experiment", I propose to handle this case by amending the rules of minOccurs conversion.

(0010113)
Jacob Wieland - Spirent
06-06-2011 12:04

Regarding your experiments, I would vote for exactly the other direction. It is much more user-friendly and understandable. We should not opt for the easier way to change the standard just to stick with a user-unfriendly, hard to understand feature.
Anyone can see from your examples that the mapping of version a) is much more natural and much simpler and, I think, also more composable.
Since choices pretty much never can stand on their own (they always must be referenced from an element as its type (or be the top-anonymous type of an element or a group reference), it just needs to be stated that whenever such a reference is made to a choice that can evaluate to an emtpy-XML-content, the field referencing the resulting union type must be optional. This can probably also be done with 2 or three well-placed sentences.

(0010156)
Gyorgy Rethy
30-06-2011 12:53

Choose the record of solution. In case of receiving an empty element the decoder shall also use the first alternative with an empty record of.

(0010158)
Gyorgy Rethy
30-06-2011 14:39

One more point: when there are more than 1 alternatives with minOccurs="0" in the XSD choice, only the first one shall be a record length(0..X) of, the rest shall be record length(1..X) of; in this way any decoding ambiguity is removed, an empty something can be received by using the first alternative only.

(0010172)
Gyorgy Rethy
01-07-2011 10:15

Proposed resolution text is in CR5852_resolution_v1.doc. Pls. review.

(0010189)
Jacob Wieland - Spirent
01-07-2011 16:44

added missing case

(0010219)
Gyorgy Rethy
13-07-2011 16:33

Added to master copy.