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.