Details
-
Improvement
-
Status: Open
-
Minor
-
Resolution: Unresolved
-
3.4.0
-
None
-
None
Description
A common mistake is to have an optional element of complex type which is a sequence of all optional elements.
This requires dfdl:emptyElementParsePolicy="treatAsAbsent", which is NOT the usual default in Daffodil.
(It is the default in the IBM-portable formats, just not in the standard daffodil-only formats)
Example: (assume context is delimited)
<sequence dfdl:separator="%WSP+"> <element name="required1" type="w:zlString" dfdl:initiator="999"/> <element name="optParent" minOccurs="0"> <complexType> <sequence> <element name="optChild1" minOccurs="0" dfdl:initiator="//" type="w:string3"/> <element name="optChild2" minOccurs="0" dfdl:initiator="[[" type="w:string3" dfdl:terminator="]]"/> </sequence> </complexType> </element> <element name="optional2" type="zlString" dfdl:initiator="opt2" minOccurs="0"/> </sequence>
In the example above, if the data is
999 opt2
We want the infoset to be
<required1/> <optional2/>
But it won't be. It will try to construct this infoset:
<required1/> <optParent/>
But you can see that the optParent is deemed present, because an empty element is perfectly allowed by this schema, and dfdl:emptyElementParsePolicy="treatAsEmpty".
Even though none of its children are present. It will then expect another separator, and will fail because there isn't one.
To fix this, one should set dfdl:emptyElementParsePolicy="treatAsAbsent", and that's what the warning message should suggest.
A less attractive fix is to add an assertion at the end of the optParent element like this:
<element name="optParent" minOccurs="0"> <complexType> <sequence> <element name="optChild1" minOccurs="0" dfdl:initiator="//" type="w:string3"/> <element name="optChild2" minOccurs="0" dfdl:initiator="[[" type="w:string3" dfdl:terminator="]]"/> <sequence> <annotation><appinfo soruce="http://www.ogf.org/dfdl/"/> <!-- One of the above children must exist or the enclosing parent does not exist --> <dfdl:assert>{ fn:exists(optChild1) or fn:exists(optChild2) }</dfdl:assert> </appinfo></annotation> </sequence> </sequence> </complexType> </element>