It's not that Daffodil is ignoring dfdl:lengthKind="0", it's just that
is allows length of zero to be valid. There are actually some use cases
where zero length is valid, and you would want this to cause a backtrack
if the children required more than zero bytes.

In this case, you just need to make it so that if the length is zero
then it does not attempt to parse any child elements. One way to
accomplish this is via dfdl:occursCountKind="expression" and
dfdl:occursCount, something like so:

  <xs:element name="payloads" minOccurs="0" maxOccurs="1
    dfdl:lengthKind="explicit" dfdl:lengthUnits="bytes"
    dfdl:length="{../payloadsLength }"
    dfdl:occursCountKind="expression" dfdl:occursCount="{
  if (../payloadsLength eq 0) then 0 else 1
  }"
    <xs:complexType>
      <xs:sequence>
        <xs:choice>
          <xs:element ref="s7:S7RequestPayloadCpuServices"/>
          <xs:element ref="s7:S7RequestPayloadWriteVar"/>
        </xs:choice>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

This changes the payloads element to be optional (minOccurs=0) and
defines the occurrences as either 0 or 1 based on the value of the
payloadsLength. If the length is 1, the payloads element will not exist
in the infoset and it will not attempt to parse the child data.

- Steve



On 1/15/19 10:39 AM, Christofer Dutz wrote:
> 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