Got it. Thank you for the explanation and tip! This is good to know.

Patrick.

> On Jun 22, 2020, at 10:42, Beckerle, Mike <mbecke...@tresys.com> wrote:
> 
> 
> The dfdl:discriminator syntax can only appear inside an 
> <xs:annotation><xs:appinfo source="http://www.ogf.org/dfdl/";> block. 
> 
> But it can appear on an element or on a sequence (or choice though that would 
> be strange)
> 
> However, there's this perhaps unexpected thing about model groups 
> (sequence/choice) and when statement-annotations (dfdl:discriminator, 
> dfdl:assert, dfdl:setVariable,.... are statements) are actually evaluated. 
> Section 9.6 of the DFDL specification talks about this. The order of 
> evaluation actually differs depending on whether the discriminator uses 
> testKind 'pattern' or testKind 'expression'. 
> 
> <xs:sequence>
>    <xs:annotation><xs:appinfo source="http://www.ogf.org/dfdl/";>
>        <dfdl:discriminator>....test here </dfdl:discriminator>
>    </xs:appnfo></xs:annotation>
>    <xs:element name="foo" ..... />
> 
> </xs:sequence>
> 
> In that sequence, you'd typically think the discriminator would be evaluated 
> and only if it is true would the element named "foo" be parsed. That's what 
> happens if the discriminator uses testKind 'pattern'. 
> 
> But.... for testKind 'expression' the annotation block for an xs:sequence is 
> evaluated potentially as late as AFTER the sequence content. This is so that 
> it can have an expression in it that examines the contents of the parsed 
> sequence. 
> 
> To get the above to mean "only parse the sequence body if the discriminator 
> is true", you have to add another layer of sequence, so that the 
> discriminator annotation is inside the first child of the sequence, and is an 
> annotation on that INNER sequence:
> 
> <xs:sequence>
>    <xs:sequence> <!-- inner sequence for discriminator -->
>      <xs:annotation><xs:appinfo source="http://www.ogf.org/dfdl/";>
>          <dfdl:discriminator>....test here </dfdl:discriminator>
>      </xs:appnfo></xs:annotation>
>    </xs:sequence>
>    <xs:element name="foo" ..... />
> 
> </xs:sequence>
> 
> That forces it to do the right thing. 
> 
> This is my preferred style for asserts and discriminators. Just always put 
> them in their own sequence. That way if you cut/paste move them around, the 
> meaning is what you normally think of when you look at the text ordering of 
> the statements and elements. With this extra sequence wrapped around them, it 
> also no longer matters what testKind they have. 
> 
> -mikeb
> 
> 
> From: Patrick Grandjean <p.r.grandj...@gmail.com>
> Sent: Saturday, June 20, 2020 9:40 AM
> To: users@daffodil.apache.org <users@daffodil.apache.org>
> Subject: Re: dfdl:choiceDispatchKey
>  
> Thank you Mike! It worked and explanation is very clear.
> 
> Can dfdl:discriminator be used as an attribute of a xs:element or only as a 
> xs:annotation?
> 
>> On Jun 18, 2020, at 4:11 PM, Beckerle, Mike <mbecke...@tresys.com> wrote:
>> 
>> To use a pattern to discriminate a choice, you would use a 
>> dfdl:discriminator statement with testKind='pattern' on each branch of the 
>> choice. That assertion is using a regex to look at the data stream, and 
>> fails if the data stream at the current position doesn't start with a 
>> non-zero-length match of the pattern.
>> 
>> E.g., something like:
>> 
>> <xs:choice>
>>    <xs:sequence>
>>       <xs:annotation><xs:appinfo ...>
>>           <!-- Must begin with from 1 to 10 'a' characters -->
>>           <dfdl:discriminator testKind="pattern">a{1,10}</dfdl:discriminator>
>>       </xs:appinfo></xs:annotation>
>>       ... rest of 'a's branch...
>>    </xs:sequence>
>>    <xs:sequence> 
>>       <xs:annotation><xs:appinfo ...>
>>           <!-- Must begin with from 1 to 10 'b' characters -->
>>           <dfdl:discriminator testKind="pattern">b{1,10}</dfdl:discriminator>
>>       </xs:appinfo></xs:annotation>
>>       ... rest of 'b's branch...
>>    </xs:sequence>
>>    ... other branches ...
>> </xs:choice>
>> 
>> Did that address your need? 
>> 
>> One detail is that the matching of the discriminator pattern isn't consuming 
>> any data. When the branch is selected and parsing starts, you are still 
>> looking at the start of the data, not after the pattern matched. An element 
>> has to absorb these characters and then go on to parse the remainder of the 
>> branch. Sometimes that's easy, sometimes a slightly different idea makes 
>> more sense:
>> 
>> <xs:choice>
>>    <xs:sequence>
>>       <!-- 
>>        element that matches the pattern. If there is no match this will be 
>> zero-length string
>>         --> 
>>       <xs:element name="aaBranchTag" type="xs:string"
>>             dfdl:lengthKind="pattern" dfdl:lengthPattern="a{1,10}"/>
>>       <xs:annotation><xs:appinfo ...>
>>           <!-- 
>>              if the match contains 1 or more characters, this is the right 
>> branch 
>>            -->
>>           <dfdl:discriminator>{ fn:string-length(./aaBranchTag) gt 0 
>> }</dfdl:discriminator>
>>       </xs:appinfo></xs:annotation>
>>       ... rest of 'a's branch...starting from after the run of 'a's. 
>>    </xs:sequence>
>>    .... other branches work similarly ....
>> </xs:choice>
>>   
>> 
>> 
>> 
>>       
>>   
>> From: Patrick Grandjean <p.r.grandj...@gmail.com>
>> Sent: Thursday, June 18, 2020 3:28 PM
>> To: users@daffodil.apache.org <users@daffodil.apache.org>
>> Subject: dfdl:choiceDispatchKey
>>  
>> Hi!
>> 
>> I recently started using dfdl:choiceDispatchKey. According to the 
>> documentation, it only accepts DFDL expressions. Is it possible to use DFDL 
>> regular expressions instead? Or is there an alternative that would accept 
>> regexes?
>> 
>> Patrick.

Reply via email to