You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@daffodil.apache.org by Steve Lawrence <sl...@apache.org> on 2019/06/17 17:11:06 UTC

Re: The second choice branch is never used ... why is that?

The core issue here is that all your fields in the DateTimeIso element
are xs:string, so Daffodil will not validate that they are correct. You
do provide some dfdl:textNumber properties to do some validation, but
they are actually ignored since they only apply for numeric types (note,
the next version of Daffodil will warn you that these properties are
ignored).

Since there's no validation, Daffodil just happily parses your Oct data
to something like this:

  <DateTimeIso>
    <Year>Oct/</Year>
    <MonthNumeric>St</MonthNumeric>
    <Day>ar</Day>
    <TimeSeparator>t</TimeSeparator>
    <HourTime> o</HourTime>
    <MinuteTime>f </MinuteTime>
    <SecondTime>fi</SecondTime>
    <TimeZoneZulu>s</TimeZoneZulu>
  </DateTimeIso>

Note how the separator and "Start of fis" is contained in the data.
Daffodil successfully parses the DateTimeIso so the choice succeeds, but
then complains that it couldn't find a following separator.

To solve this, you'll need to apply validation to these fields. In some
cases, just making the field an xs:int will enable the dfdl:textNumber
properties and will cause failures/backtracking. But an even better
method would be to use the xs:dateTime type and use date time parsing,
something like this:

  <xs:choice>
    <xs:element name="DateTimeIso" type="xs:dateTime"
      dfdl:calendarPatternKind="explicit"
      dfdl:calendarPattern="yyyyMMdd'T'HHmmddXX" />
    <xs:element name="MonthName" type="xs:string"
      dfdl:length="3"
      dfdl:lengthKind="explicit" />
  </xs:choice>

So Daffodil will find all the text up to the delimiter, and then try to
parse it as a date time using the provided pattern. If that fails, it
will then try to parse it as a three letter month name. You might even
want to have the MonthName use delimited length, and then use a
enumeration restriction when you want to validate whether that MonthName
is a valid three letter month name or not. This goes back to the
discussions of well-formed vs valid.




On 6/17/19 11:16 AM, Costello, Roger L. wrote:
> Hello DFDL community,
> 
> My input file contains three fields, separated by slash.
> 
> The first and last fields contain strings.
> 
> The middle field contains either an ISO date/time or a 3-letter month (Jan, Feb, 
> etc.)
> 
> So, the middle field is a choice.
> 
> This input
> 
> Birthday/20190617T182530Z/John's birthday
> 
> Produces this XML
> 
> <input>
> <title>Birthday</title>
> <date>
> <DateTimeIso>
> <Year>2019</Year>
> <MonthNumeric>06</MonthNumeric>
> <Day>17</Day>
> <TimeSeparator>T</TimeSeparator>
> <HourTime>18</HourTime>
> <MinuteTime>25</MinuteTime>
> <SecondTime>30</SecondTime>
> <TimeZoneZulu>Z</TimeZoneZulu>
> </DateTimeIso>
> </date>
> <note>John's birthday</note>
> </input>
> 
> But this input
> 
> New tasking/Oct/Start Fiscal Year
> 
> Results in this error message
> 
> *[error] Parse Error: Separator '/' not found.*
> 
> *First Question*: Why is that? Why can’t Daffodil recognize that “Oct” doesn’t 
> match my schema’s first choice branch and then use the second choice branch? I 
> noticed that if I reverse the choice branches in my DFDL schema, then this input 
> parses fine, but then the first input fails.
> 
> Below is my DFDL schema.
> 
> *Second Question*: Is there a better way to express the file format than how my 
> DFDL schema does it?  /Roger
> 
> <xs:elementname="input">
> <xs:complexType>
> <xs:sequencedfdl:separator="/"dfdl:separatorPosition="infix">
> <xs:elementname="title"type="xs:string"/>
> <xs:elementname="date">
> <xs:complexType>
> <xs:choice>
> <xs:elementname="DateTimeIso">
> <xs:complexType>
> <xs:sequencedfdl:separator="">
> <xs:elementname="Year"type="xs:string"
>                                          dfdl:length="4"dfdl:lengthKind="explicit"
>                                          dfdl:textNumberCheckPolicy="strict"
>                                          dfdl:textNumberPattern="####"/>
> <xs:elementname="MonthNumeric"type="xs:string"
>                                          dfdl:length="2"dfdl:lengthKind="explicit"
>                                          dfdl:textNumberCheckPolicy="strict"
>                                          dfdl:textNumberPattern="##"/>
> <xs:elementname="Day"type="xs:string"
>                                          dfdl:length="2"dfdl:lengthKind="explicit"
>                                          dfdl:textNumberCheckPolicy="strict"
>                                          dfdl:textNumberPattern="##"/>
> <xs:elementname="TimeSeparator"type="xs:string"
>                                          dfdl:length="1"dfdl:lengthKind="explicit"/>
> <xs:elementname="HourTime"type="xs:string"
>                                          dfdl:length="2"dfdl:lengthKind="explicit"
>                                          dfdl:textNumberCheckPolicy="strict"
>                                          dfdl:textNumberPattern="##"/>
> <xs:elementname="MinuteTime"type="xs:string"
>                                          dfdl:length="2"dfdl:lengthKind="explicit"
>                                          dfdl:textNumberCheckPolicy="strict"
>                                          dfdl:textNumberPattern="##"/>
> <xs:elementname="SecondTime"type="xs:string"
>                                          dfdl:length="2"dfdl:lengthKind="explicit"
>                                          dfdl:textNumberCheckPolicy="strict"
>                                          dfdl:textNumberPattern="##"/>
> <xs:elementname="TimeZoneZulu"type="xs:string"
>                                          dfdl:length="1"dfdl:lengthKind="explicit"/>
> </xs:sequence>
> </xs:complexType>
> </xs:element>
> <xs:elementname="MonthName"type="xs:string"dfdl:length="3"
>                              dfdl:lengthKind="explicit"/>
> </xs:choice>
> </xs:complexType>
> </xs:element>
> <xs:elementname="note"type="xs:string"/>
> </xs:sequence>
> </xs:complexType>
> </xs:element>
>