I agree. I'll add that in solution 2 it would be possible to have a num
value that doesn't correspond to the right initiator/terminator, since
the A/B choice is completely speculative and doesn't reference "num" at
all. This may or may not be a good thing depending on the kinds of data
you want to support.
To chnage that, and also improve performance as Mike mentioned could be
a problem, you could use direct dispatch:
<xs:choice dfdl:choiceDispatchKey="{ ./num }">
<xs:elementname="A" type="xs:string" dfdl:initiator="("
dfdl:terminator=")" dfdl:choiceBranchKey="1" />
<xs:elementname="B" type="xs:string" dfdl:initiator="["
dfdl:terminator="]" dfdl:choiceBranchKey="2" />
</xs:choice>
This avoids speculative parsing and ensures the correct
initiators/terminators are used based on the value of num, but avoids
having the delimiters determined by an expression.
- Steve
On 6/3/19 9:22 AM, Beckerle, Mike wrote:
> My preference is the latter. I think expressions for delimiters should be
> avoided if possible.
>
>
> One may get better diagnostics here if in fact what is found in the data
> stream
> is neither a "(" nor "[".
>
>
> But, if you had a larger number of branch cases, one could argue in favor of
> the
> expression for performance reasons.
>
> --------------------------------------------------------------------------------
> *From:* Costello, Roger L. <[email protected]>
> *Sent:* Monday, June 3, 2019 9:07:21 AM
> *To:* [email protected]
> *Subject:* Best Practice: dynamically compute initiator/terminator or choice
> with initiatedContent="yes"?
>
> Hello DFDL community,
>
> My input file has a number (num), followed by a comma-separated pair of
> values,
> enclosed within either round parentheses or square parentheses. If num=1 then
> the initiator and terminator are rounded parentheses. If num=2 then the
> initiator and terminator are square parentheses.
>
> Below are two solutions to the problem. The first solution dynamically
> computes
> the initiator and terminator. The second solution uses a choice with
> dfdl:initiatedContent="yes".
>
> Which solution is better?
>
> *Solution #1 Dynamically Compute initiator and terminator*
>
> <xs:elementname="input">
> <xs:complexType>
> <xs:sequencedfdl:separator="%NL;"dfdl:separatorPosition="infix">
> <xs:elementname="num"type="xs:integer"/>
> <xs:sequencedfdl:initiator="{if (num eq 1) then '(' else '[' }"
> dfdl:terminator="{if (num eq 1) then ')' else ']' }"
> dfdl:separator=","dfdl:separatorPosition="infix">
> <xs:elementname="A"type="xs:string"/>
> <xs:elementname="B"type="xs:string"/>
> </xs:sequence>
> </xs:sequence>
> </xs:complexType>
> </xs:element>
>
> *Solution #2 Choice with initiatedContent="yes"*
>
> <xs:elementname="input">
> <xs:complexType>
> <xs:sequencedfdl:separator="%NL;"dfdl:separatorPosition="infix">
> <xs:elementname="num"type="xs:integer"/>
> <xs:choicedfdl:initiatedContent="yes">
> <xs:elementname="A"type="xs:string"dfdl:initiator="("dfdl:terminator=")"/>
> <xs:elementname="B"type="xs:string"dfdl:initiator="["dfdl:terminator="]"/>
> </xs:choice>
> </xs:sequence>
> </xs:complexType>
> </xs:element>
>