Christofer,

So looking at your schemas I think the concept you are missing is that just 
because something is zero length doesn't mean the parser won't try to parse 
against it.


A DFDL schema could parse, with zero data, consume zero bits of course, yet 
still populate an infoset with default values, empty strings, zero-length 
hexBinary byte arrays, nilled elements, or computed elements. The parser 
doesn't turn on/off based on zero length being available.


What you need do is use minOccurs="0", and dfdl:occursCountKind="expression" 
and dfdl:occursCount="{ if (../parametersLength gt 0) then 1 else 0 }"


What is maybe a little confusing is that you actually must specify both - the 
length AND whether there are occurrences or not. If there are no occurrences, 
the length won't be used, but if there are, the parser must be able to 
determine how long they are.


...mike beckerle

Tresys




________________________________
From: Christofer Dutz <christofer.d...@c-ware.de>
Sent: Tuesday, January 15, 2019 10:39:03 AM
To: dev@daffodil.apache.org
Subject: Daffodil ignoring dfdl:length=0 when dfdl:lengthKind=explicit

Hi all,

after working though the 6 tutorials on DFDL in general I think I have a much 
greater understanding on how I have to do things. I even managed to get my S7 
protocol messages schema in a somewhat working condition.
Right now I’m having one problem:
A S7 Messages consists of a header, a number of variable length parameters and 
a number of variable length payloads.
As parameters and payloads are of variable length, the header contains a 
“parametersLength” and “payloadsLength” field which contains the number of 
bytes the parameters and payloads require in total.
So I defined something like this:


<xs:element name="parametersLength" type="s7:short"/>
<xs:element name="payloadsLength" type="s7:short"/>
<xs:element name="parameters" dfdl:lengthKind="explicit" 
dfdl:lengthUnits="bytes" dfdl:length="{../parametersLength}">
    <xs:complexType>
        <xs:sequence>
            <xs:choice>
                <xs:element ref="s7:S7GeneralParameterSetupCommunication"/>
                <xs:element ref="s7:SS7RequestParameterCPUService"/>
                <xs:element ref="s7:S7RequestParameterReadVar"/>
                <xs:element ref="s7:S7RequestParameterWriteVar"/>
            </xs:choice>
        </xs:sequence>
    </xs:complexType>
</xs:element>
<xs:element name="payloads" dfdl:lengthKind="explicit" dfdl:lengthUnits="bytes" 
dfdl:length="{../payloadsLength}">
    <xs:complexType>
        <xs:sequence>
            <xs:choice>
                <xs:element ref="s7:S7RequestPayloadCpuServices"/>
                <xs:element ref="s7:S7RequestPayloadWriteVar"/>
            </xs:choice>
        </xs:sequence>
    </xs:complexType>
</xs:element>

However in a request, that doesn’t contain any payloads, daffodil still tries 
to parse the payloads, even if the “length” of the sequence is set to explicit 
and to a length of 0 … why is it doing that?
Each parameter and payloads first byte contains the code that tells the parser 
what type it is and each of the elements in my schema use a discriminator to 
tell the parser which input it is requiring.


<xs:element name="S7RequestPayloadCpuServices">
    <xs:annotation>
        <xs:appinfo source="http://www.ogf.org/dfdl/";>
            <dfdl:discriminator test="{./type eq 0}"/>
        </xs:appinfo>
    </xs:annotation>
    <xs:complexType>
        <xs:sequence>
            <xs:element name="type" type="s7:byte"/>
            <xs:element name="transportSize" type="s7:byte"/><!-- fixed="9"-->
            <xs:element name="length" type="s7:byte"/>
            <xs:element name="sslId" type="s7:short"/>
            <xs:element name="sslIndex" type="s7:short"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

Hope it’s correct to do things like that …

The effect is that Daffodil has correctly parsed all the parameters and as 
there is no payload (payloadLength = 0) it shouldn’t try to parse a payload, 
but it does and when reading the first byte it instantly fails as there is no 
data to parse anymore.


Chris

Reply via email to