What you've written is not correct.

The discriminator doesn't go in the appnfo block of the choice itself, but 
somewhere inside each branch.


The syntax is bulky because of XSD requiring anything that isn't just an 
attribute to be bulky like this.


The point of a discriminator is not to decide, but to decide *early*. Sometimes 
you have enough information to lock down which branch it is, before you have 
parsed everything about the branch.  If after a few things on the branch you 
know for sure that the right branch has been selected, that's where you put the 
discriminator. As early as when you know.


This is helpful, because then if something goes wrong on the branch after the 
discriminator has evaluated to true, then that's a problem with data that is on 
that branch. Not a situation where you want to try other branches. Trying other 
branches wants to be cut off because you could get false matches, you will 
almost certainly get very poor diagnostic behavior.


This is very useful at reducing unnecessary backtracking and insuring that 
diagnostics are much more relevant to the situation.


The difference between an assert and a discriminator, is that a discriminator - 
when true, locks the branch selection. When false both assert and discriminator 
have the same behavior - try the next alternative.


For performance reasons the choiceDispatchKey and choiceBranchKey properties 
are greatly preferred. They eliminate backtracking behavior entirely and 
convert it to a constant-time dispatch.


But sometimes backtracking through possibilities is unavoidable.

________________________________
From: Costello, Roger L. <[email protected]>
Sent: Friday, December 14, 2018 2:26:37 PM
To: [email protected]
Subject: Why are dfdl:discriminators so .... different?


Hi DFDL community,



Below is an xs:choice that is part of my DFDL schema for Windows executable 
files. Here is my understanding of implementing choices in DFDL:



An xs:choice consists of a series of sequences.
                Daffodil uses dfdl:descrimintor to decide which
               sequence to choose.



Is that correct?



Question: When I do this discriminator stuff, I blindly follow the pattern 
shown below, i.e., embed dfdl:discriminator within xs:appinfo. When I try to 
explain discriminators to people, I just know that they are going to ask: Why? 
Why are dfdl:discriminators embedded within xs:appinfo? Discriminators seem to 
be handled very different from everything else, why?



How do I respond to these questions?  /Roger



<xs:choice>
     <xs:sequence>
            <xs:annotation>
                <xs:appinfo source="http://www.ogf.org/dfdl/";>
                    <dfdl:discriminator 
test="{fn:lower-case(xs:string(Hidden_signature)) eq '0b01'}" />
                </xs:appinfo>
            </xs:annotation>

            element declarations for 32-bit executable

     </xs:sequence>
     <xs:sequence>
            <xs:annotation>
                <xs:appinfo source="http://www.ogf.org/dfdl/";>
                    <dfdl:discriminator 
test="{fn:lower-case(xs:string(Hidden_signature)) eq '0b02'}"/>
                </xs:appinfo>
            </xs:annotation>

            element declarations for 64-bit executable

     </xs:sequence>
     <xs:sequence>
            <xs:annotation>
                <xs:appinfo source="http://www.ogf.org/dfdl/";>
                    <dfdl:discriminator 
test="{fn:lower-case(xs:string(Hidden_signature)) eq ‘0701'}"/>
                </xs:appinfo>
            </xs:annotation>

            element declarations for ROM image

     </xs:sequence>

</xs:choice>


Reply via email to