The DFDL spec says that all branches in
an xs:choice must not have minOccurs '0' and if all branches are processed
without a match then it is a processing error. But the DFDL spec also allows
the creation of an empty xs:choice, that is, a choice without any branches
at all. Some questions arise:
1) What happens when choiceLengthKind
is 'explicit' - SDE ? Insist that choiceLength is '0' ?
2) What happens if choiceBranchRef is
specified ?
3) Assuming any syntax matches, an empty
choice always parses successfully. Read on...
I have been using an empty choice for
modeling data formats where user-defined extensions are permitted. This
was the mechanism agreed upon by the WG to model this scenario in the absence
of xs:any support in DFDL 1.0. Here's an example from a schema that models
the TLOG retail format:
<xsd:choice>
<xsd:element
ref="TransactionRecord00"/>
<xsd:element
ref="TransactionRecord01"/>
<xsd:element
ref="TransactionRecord04"/>
<xsd:element
ref="TransactionRecord05"/>
<xsd:element
ref="TransactionRecord98"/>
<xsd:group
ref="choice_Custom"/>
</xsd:choice>
<!-- Group for all
user-defined records -->
<xsd:group name="choice_Custom">
<xsd:choice>
<!--
Insert elements here -->
</xsd:choice>
</xsd:group>
The intent is that the user adds his
own records in the choice_Custom group. If an unknown record is parsed
that fails to match any of the pre-defined records and any of the user-defined
records, it will cause a processing error.
However that didn't actually work. Because
choiceCustom is initially empty, it will parse successfully against any
input and in doing so discriminate the outer choice, meaning the processing
error is not thrown. As soon as an element is added to choice_Custom,
then it behaves as originally intended - an unknown record causes a processing
error in choice_Custom, so the outer choice never discriminates.
To work around this I added an assert
to the choice to ensure it fails when empty.
<!-- Group for all
user-defined records -->
<xsd:group name="choice_Custom">
<xsd:choice>
<!--
Insert elements here -->
<!--
If we get here ensure choice fails -->
<xsd:sequence>
<xsd:annotation><xsd:appinfo
source="http://www.ogf.org/dfdl/">
<dfdl:assert>{fn:false()}</dfdl:assert>
</xsd:appinfo></xsd:annotation>
</xsd:sequence>
</xsd:choice>
</xsd:group>
So is an empty choice a genuinely useful construct to allow? It didn't
actually help my scenario in 3). Are there any where it would make sense?
Regards
Steve Hanson
Architect, Data Format Description Language (DFDL)
Co-Chair, OGF
DFDL Working Group
IBM SWG, Hursley, UK
smh@uk.ibm.com
tel:+44-1962-815848
Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number
741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6
3AU