I found the issue.

I noticed that you import the DFDLGeneralFormat.dfdl.xml, but then you don't 
use it.

So I checked, and in your list of property definitions in dfdl:format they are 
almost all the same as if you had ref="ama:GeneralFormat" except for one 
crucial one.

You have separatorSuppressionPolicy="never".

That's not what you want. You want "anyEmpty".

This separatorSuppressionPolicy property is among the most difficult to deal 
with in the spec.

The "never" value means "never suppress separators, even if the item is 
missing". That is really about fixed length arrays and fixed-size tuples where 
the separators are always going to appear even if the element content is 
missing.

Think sparse data formats with data like "/1,2,,,5,,7,8/" where the missing 
pieces are still delimited by separators.

I think the diagnostic message is not good here, and will create a bug ticket 
about it. It should say specifically that it was looking for the separator, not 
that the element initiator isn't present. Or it should say it didn't find the 
element because it didn't find the initiator, AND also didn't find the 
associated separator.

If I remove all your format properties and just use
<dfdl:format ref="ama:GeneralFormat"/> then it works.

One other minor thing: You had textStringPadCharacter="%WSP;" which is a 
schema-definition error. I changed it to %SP; which is probably what you 
intended, and that's the value in ama:GeneralFormat, so I removed it entirely.

The TDML file that has the test that shows it working is attached.


________________________________
From: Beckerle, Mike <[email protected]>
Sent: Wednesday, February 5, 2020 9:07 AM
To: Patrick Grandjean <[email protected]>; [email protected] 
<[email protected]>
Subject: Re: Optional element with initiator

Sorry for duplicate. This time to users list also.

I will try to reproduce the issue and get back to you.
________________________________
From: Patrick Grandjean <[email protected]>
Sent: Tuesday, February 4, 2020 2:31 PM
To: [email protected] <[email protected]>
Subject: Re: Optional element with initiator

Thank for the answer.

Unfortunately, if I try to remove any dfdl:occursCountKind I get an error from 
daffodil saying this attribute is missing.

I have removed the postfix attribute, thank you for the tip!

I have set all elements to be optional (minOccurs="0"), but I still get an 
Initiator exception:

diff:
  No differences
----------------------------------------------------------------- 91
parser: <Initiator/>
bitPosition: 4096
data:
            │                                        │
  87654321  0011 2233 4455 6677 8899 aabb ccdd eeff  0123456789abcdef
  00000200: 3530 3030 3030 3130 3030 3030 3030 3230  5000001000000020
  00000210: 3030 4555 5232 2020 2020 2020 2020 3030  00EUR2␣␣␣␣␣␣␣␣00
infoset:
  <record>
    <it02>
     [....]
    </it02>
    <it03 />
  </record>
diff:
  No differences
failure:
  Parse Error: Initiator '3' not found
  Schema context: it03 Location line 71 column 14 in 
file:/path/to/apache-daffodil-2.5.0-incubating-bin/bin/../../src/main/resources/grammar.dfdl.xsd
  Data location was preceding byte 512

I would expect that if an initiator is not found, the parser would backtrack 
and try the next element in the sequence. Is there a policy to be set?

I have tried to replace the initiators with elements having fixed values, but 
it seems that the fixed value is not checked. Example below, with fixed="1":

<xs:element name="recordIdentifier" type="xs:string" fixed="1" dfdl:length="1" 
dfdl:lengthKind="explicit" />



On Mon, Feb 3, 2020 at 3:17 PM Beckerle, Mike 
<[email protected]<mailto:[email protected]>> wrote:
I see a couple issues here.

First your record element is not optional but you have 
dfdl:occursCountKind="implicit" on it, suggesting you wanted minOccurs="0" on 
it, or maxOccurs="unbounded",  but you didn't put that.

Same for it02 element, which probably wants minOccurs="0".

Second, your records type has a sequence with postfix newline separator.
Your inner sequence inside the record type *also* has postfix newline separator.

This means you will have TWO newlines required at the end of your data.

If you don't have two newlines, then it's going to backtrack and, while I can't 
construct a specific reason why it ends up giving you an error on it03, I can 
imagine that could happen.

I suggest removing the postfix from the inner sequence so it is only infix 
separated, and the final newline will come from the outer sequence.

Then I suggest making it02 element optional and record element optional or 
removing the dfdl:occursCountKind="implicit" from either or both of them.

Then try again. Post your results here again.

You may want to turn on the trace feature. You get TONS of sometimes obscure 
output from trace (fixing that is on our roadmap), but often one can wade 
through it and spot where things go wrong.

If your format has many many of these different record sub-types you will 
eventually want to switch away from using initiators to a choice using the 
dfdl:choiceDispatchKey property.

But we should get what you started with working properly first.




________________________________
From: Patrick Grandjean 
<[email protected]<mailto:[email protected]>>
Sent: Monday, February 3, 2020 2:23 PM
To: [email protected]<mailto:[email protected]> 
<[email protected]<mailto:[email protected]>>
Subject: Optional element with initiator

Hi!

I'm trying to create my first DFDL schema to parse a fixed column format. The 
format may change from one line to the other depending on the first character 
of the line. Some lines are optional, therefore I use minOccurs="0" and 
dlfl:occursCountKind="implicit". Here is the schema:


<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema";
           xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/";
           xmlns:ex="http://example.com";
           xmlns:ama="http://www.amadeus.com";
           targetNamespace="http://www.amadeus.com";
           elementFormDefault="unqualified">

    <xs:include 
schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd" />
    <xs:include schemaLocation="IT01.dfdl.xsd" />
    <xs:include schemaLocation="IT02.dfdl.xsd" />
    <xs:include schemaLocation="IT03.dfdl.xsd" />
    <xs:include schemaLocation="IT05.dfdl.xsd" />

    <xs:annotation>
        <xs:appinfo source="http://www.ogf.org/dfdl/";>
            <dfdl:format alignment="1"
                         alignmentUnits="bytes"
                         encoding="ASCII"
                         encodingErrorPolicy="replace"
                         escapeSchemeRef=""
                         floating="no"
                         ignoreCase="no"
                         initiatedContent="no"
                         initiator=""
                         leadingSkip="0"
                         lengthKind="implicit"
                         lengthUnits="bytes"
                         outputNewLine="%LF;"
                         representation="text"
                         separator=""
                         separatorSuppressionPolicy="never"
                         sequenceKind="ordered"
                         terminator=""
                         textBidi="no"
                         textPadKind="none"
                         textStringJustification="center"
                         textStringPadCharacter="%WSP;"
                         textTrimKind="padChar"
                         trailingSkip="0"
                         truncateSpecifiedLengthString="no"/>
        </xs:appinfo>
    </xs:annotation>

    <xs:element name="records" type="ama:Records" />

    <xs:complexType name="Records">
        <xs:sequence dfdl:separator="%NL;" dfdl:separatorPosition="postfix">
            <xs:element name="it01" minOccurs="0" maxOccurs="1" type="ama:IT01" 
dfdl:initiator="1" dfdl:occursCountKind="implicit" />
            <xs:element name="record" type="ama:Record" minOccurs="1" 
dfdl:occursCountKind="implicit" />
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="Record">
        <xs:sequence dfdl:separator="%NL;" dfdl:separatorPosition="postfix">
            <xs:element name="it02" type="ama:IT02" dfdl:initiator="2" 
dfdl:occursCountKind="implicit" />
            <xs:element name="it03" minOccurs="0" type="ama:IT03" 
dfdl:initiator="3" dfdl:occursCountKind="implicit" />
            <xs:element name="it05" minOccurs="0" type="ama:IT05" 
dfdl:initiator="5" dfdl:occursCountKind="implicit" />
        </xs:sequence>
    </xs:complexType>

</xs:schema>

A file would look like this:

1......
2......
5......

Elements it01 (line starting with '1') and it02 (line starting with '2') are 
parsed successfully. Element it03 is missing, but since it is optional it is 
OK. The problem is that the Daffodil raises an error saying it has not found 
initiator '3'. How to make the initiator optional?

Patrick.
<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<tdml:testSuite
  description="Bug report"
  xmlns:tdml="http://www.ibm.com/xmlns/dfdl/testData";
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
  xmlns:xml="http://www.w3.org/XML/1998/namespace";
  xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/";
  xmlns:xs="http://www.w3.org/2001/XMLSchema";
  xmlns:gpf="http://www.ibm.com/dfdl/GeneralPurposeFormat";
  xmlns:daf="urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:ext"
  xmlns:ex="http://example.com";
  xsi:schemaLocation="http://www.ibm.com/xmlns/dfdl/testData tdml.xsd"
  defaultRoundTrip="onePass"
  
  xmlns:ama="http://example.com";
  >

  <tdml:defineSchema name="s1" elementFormDefault="unqualified">

  <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd" />

  <!-- 
  
    In format below. Remove separatorSuppressionPolicy, or change
    value to "never" to reproduce the problem. You will get an error 
    about initiator "3" not found.
    
    separatorSuppressionPolicy="never" means the separators will be present.
    It is generally for fixed-length arrays, or sequences that are fixed-length
    tuples of elements.  
   -->
     
  <dfdl:format 
    ref="ex:GeneralFormat" 
    separatorSuppressionPolicy="anyEmpty" 
   />

  <xs:element name="records" type="ama:Records" />

  <xs:complexType name="Records">
    <xs:sequence dfdl:separator="%NL;" dfdl:separatorPosition="postfix">
      <xs:element name="it01" minOccurs="0" type="ama:IT01" dfdl:initiator="1" />
      <xs:element name="record" type="ama:Record" />
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="Record">
    <xs:sequence dfdl:separator="%NL;">
      <xs:element name="it02" type="ama:IT02" dfdl:initiator="2" />
      <xs:element name="it03" minOccurs="0" type="ama:IT03" dfdl:initiator="3" />
      <xs:element name="it05" minOccurs="0" type="ama:IT05" dfdl:initiator="5" />
    </xs:sequence>
  </xs:complexType>

  <xs:simpleType name="delimString" dfdl:lengthKind="delimited">
    <xs:restriction base="xs:string" />
  </xs:simpleType>

  <xs:simpleType name="IT01">
    <xs:restriction base="ama:delimString" />
  </xs:simpleType>

  <xs:simpleType name="IT02">
    <xs:restriction base="ama:delimString" />
  </xs:simpleType>

  <xs:simpleType name="IT03">
    <xs:restriction base="ama:delimString" />
  </xs:simpleType>

  <xs:simpleType name="IT04">
    <xs:restriction base="ama:delimString" />
  </xs:simpleType>

  <xs:simpleType name="IT05">
    <xs:restriction base="ama:delimString" />
  </xs:simpleType>

  </tdml:defineSchema>
  
  <tdml:parserTestCase name="test1"  model="s1">
    <tdml:document><![CDATA[1aaa
2bbb
5eee
]]></tdml:document>
    
     
    <tdml:infoset>
    <tdml:dfdlInfoset>
      <ama:records>
      <it01>aaa</it01>
      <record>
        <it02>bbb</it02>
        <it05>eee</it05>
      </record>
      </ama:records>
    </tdml:dfdlInfoset>
    </tdml:infoset>
     
    
  </tdml:parserTestCase>
  
</tdml:testSuite>

Reply via email to