We handle elements having xs:choice complex types.
However, we don’t support anonymous choice groups
(that is, an unnamed choice group in the middle, beginning,
or end of a sequence which may contain other elements).
A DFDL schema author may write a sequence like this:
<xs:complexType name="NestedUnionType">
<xs:sequence>
<xs:element name="first_tag" type="idl:int32"/>
<xs:choice dfdl:choiceDispatchKey="{xs:string(./first_tag)}">
<xs:element name="foo" type="idl:FooType" dfdl:choiceBranchKey="1 2"/>
<xs:element name="bar" type="idl:BarType" dfdl:choiceBranchKey="3 4"/>
</xs:choice>
<xs:element name="second_tag" type="idl:int32"/>
<xs:choice dfdl:choiceDispatchKey="{xs:string(./second_tag)}">
<xs:element name="fie" type="idl:FieType" dfdl:choiceBranchKey="1"/>
<xs:element name="fum" type="idl:FumType" dfdl:choiceBranchKey="2"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
Daffodil will parse and unparse the above sequence fine,
but the C code generator will not generate correct code
(no _choice members or unions will be declared for the type).
It might be possible to generate C code that looks like this:
typedef struct NestedUnion
{
InfosetBase _base;
int32_t first_tag;
size_t _choice_1; // choice of which union field to use
union
{
foo foo;
bar bar;
};
int32_t second_tag;
size_t _choice_2; // choice of which union field to use
union
{
fie fie;
fum fum;
};
} NestedUnion;
However, the Daffodil devs have looked at DFDL integration
for other systems like Apache Drill, NiFi, Avro, etc.,
and these systems generally do not allow anonymous choices.
Hence, any DFDL schema having anonymous choices
doesn’t integrate well with any of these systems
unless we generate a child element with a generated name
(which makes paths awkward, etc.).
Hence, it seems better to say that
codegen-c’s DFDL subset doesn’t allow anonymous choices
and DFDL schema authors should write their schema like this:
<xs:complexType name="NestedUnionType">
<xs:sequence>
<xs:element name="first_tag" type="idl:int32"/>
<xs:element name="first_choice">
<xs:complexType>
<xs:choice dfdl:choiceDispatchKey="{xs:string(../first_tag)}">
<xs:element name="foo" type="idl:FooType" dfdl:choiceBranchKey="1 2"/>
<xs:element name="bar" type="idl:BarType" dfdl:choiceBranchKey="3 4"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element name="second_tag" type="idl:int32"/>
<xs:element name="second_choice">
<xs:complexType>
<xs:choice dfdl:choiceDispatchKey="{xs:string(../second_tag)}">
<xs:element name="fie" type="idl:FieType" dfdl:choiceBranchKey="1"/>
<xs:element name="fum" type="idl:FumType" dfdl:choiceBranchKey="2"/>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
The C code generator will generate _choice members and unions
for the first_choice and second_choice elements,
and such a schema will integrate better with other systems too.