Thanks Steve - awesome!

I tried the second approach that you provided. See below. When I run it, I get 
this error message:

[error] Parse Error: Failed to populate Lookup_Table_Entry[1]. Cause: Parse 
Error: All choice alternatives failed. Reason(s): List(Parse Error: Alternative 
failed. Reason(s): List(Parse Error: Assertion failed: { . eq 1 } failed

On the other hand, if I switch the order of the sequences in xs:choice, then I 
get no error. Why do I get an error with the sequences in one order but no 
error in another order?  /Roger

<xs:element name="Lookup_Table_Entry" dfdl:length="32" 
dfdl:lengthKind="explicit" dfdl:lengthUnits="bits">
    <xs:annotation>
        <xs:appinfo source="http://www.ogf.org/dfdl/";>
            <dfdl:discriminator test="{ 
                fn:not(
                (fn:exists(./Hint_Name_Table_RVA)) and
                (./Hint_Name_Table_RVA eq 0) and
                (./Name_Flag eq 0)
                )
                }" />
        </xs:appinfo>
    </xs:annotation>
    <xs:complexType>
        <xs:choice>
            <xs:sequence>
                <xs:element name="Ordinal_Number" type="unsignedint16" />
                <xs:element name="Zero" type="unsignedint15">
                    <xs:annotation>
                        <xs:appinfo source="http://www.ogf.org/dfdl/";>
                            <dfdl:discriminator test="{ . eq 0 }" />
                        </xs:appinfo>
                    </xs:annotation>
                </xs:element>
                <xs:element name="Ordinal_Flag" type="unsignedint1">
                    <xs:annotation>
                        <xs:appinfo source="http://www.ogf.org/dfdl/";>
                            <dfdl:discriminator test="{ . eq 1 }" />
                        </xs:appinfo>
                    </xs:annotation>
                </xs:element>
            </xs:sequence>
            <xs:sequence>
                <xs:element name="Hint_Name_Table_RVA" type="unsignedint31" />
                <xs:element name="Name_Flag" type="unsignedint1">
                    <xs:annotation>
                        <xs:appinfo source="http://www.ogf.org/dfdl/";>
                            <dfdl:discriminator test="{ . eq 0 }" />
                        </xs:appinfo>
                    </xs:annotation>
                </xs:element>
            </xs:sequence>
        </xs:choice>
    </xs:complexType>
</xs:element>



-----Original Message-----
From: Steve Lawrence <[email protected]> 
Sent: Monday, February 11, 2019 8:10 AM
To: [email protected]; Costello, Roger L. <[email protected]>
Subject: [EXT] Re: Can bits be cast to string, concatenated, and then cast to 
an unsigned int?

Concating bit values will not work because there are no constructor functions 
that accept a bit string. The dfdl:setBits() function can be used, but only for 
only for bytes (i.e. 8 bits or less). You could always just use math to 
construct an int, e.g.:

  ./bit1 * fn:pow(2,31) +
  ./bit2 * fn:pow(2,30) +
  ...
  ./bitN * fn:pow(2,0)

It would probably be more efficient to expand the fn:pow's to their actual 
values, but this gives the idea.

That said, I think an approach that makes for a more descriptive schema that is 
easier to understand is to use a choice where each branch of the choice parses 
the 30 bits differently, and a discriminator is used to ensure the correct 
branch is taken based on the lst bit. Something like:

  <xs:choice>
    <xs:sequence>
      <xs:element name="OrdinalNumber" dfdl:length="16" ... />
      <xs:element name="Zero" dfdl:length="15 ... />
      <xs:element name="Flag" dfdl:length=1" ... >
        <xs:annotation>
          <xs:appinfo source="http://www.ogf.org/dfdl/";>
            <dfdl:discriminator test="{ . eq 1 }" />
          </xs:appinfo>
        </xs:annotation>
      </xs:element>
    </xs:sequence>
    <xs:sequence>
      <xs:element name="HintNameTableRVA" dfdl:length="31" ... />
      <xs:element name="Flag" dfdl:length=1" ... >
        <xs:annotation>
          <xs:appinfo source="http://www.ogf.org/dfdl/";>
            <dfdl:discriminator test="{ . eq 0 }" />
          </xs:appinfo>
        </xs:annotation>
      </xs:element>
    </xs:sequence>
  </xs:choice>

This is bit inefficient since it requires parsing the same 32 bits twice if the 
last bit is a 0, but it's much easier to understand what data looks like.

- Steve


On 2/11/19 6:43 AM, Costello, Roger L. wrote:
> Hello DFDL Community,
> 
> My input file contains a 32-bit field (bit 0 to bit 31). Bit 31 
> determines how to interpret the other bits: if bit 31 = 1 then bits 0 
> to 15 is an unsigned int denoting an ordinal number and the other bits 
> must be zero. If bit 30 = 0 then bits 0 to 30 is an unsigned int 
> denoting a hint/name table RVA. The following graphic illustrates the 
> structure:
> 
> How to express this in DFDL? I figured that I would create a hidden 
> group that contains 32 1-bit elements. I would have a choice that 
> expresses this: If hidden bit 31 = 1 then choose the ordinal_number 
> element, otherwise (hidden bit 31 = 0) choose hint_name_table_RVA element.
> 
> The value of ordinal_number is calculated by concatenating hidden bit 
> 0 with hidden bit 1, ..., hidden bit 15. Then, cast that to unsigned int.
> 
> The value of hint_name_table_RVA is calculated by concatenating hidden 
> bit 0 with hidden bit 1, ..., hidden bit 30. Then, cast that to unsigned int.
> 
> You can see my schema below. Unfortunately, it fails. What is the 
> right way to approach this problem, please?  /Roger
> 
> <xs:elementname="Ordinal_Number"type="unsignedint16"dfdl:inputValueCalc="{
>      unsignedint16(
>      fn:concat(./Hidden_Lookup_Table_bit0,
>      ./Hidden_Lookup_Table_bit1,
>      ./Hidden_Lookup_Table_bit2,
>      ./Hidden_Lookup_Table_bit3,
>      ./Hidden_Lookup_Table_bit4,
>      ./Hidden_Lookup_Table_bit5,
>      ./Hidden_Lookup_Table_bit6,
>      ./Hidden_Lookup_Table_bit7,
>      ./Hidden_Lookup_Table_bit8,
>      ./Hidden_Lookup_Table_bit9,
>      ./Hidden_Lookup_Table_bit10,
>      ./Hidden_Lookup_Table_bit11,
>      ./Hidden_Lookup_Table_bit12,
>      ./Hidden_Lookup_Table_bit13,
>      ./Hidden_Lookup_Table_bit14,
>      ./Hidden_Lookup_Table_bit15))
>      }"/>
> 
> <xs:elementname="Hint_Name_Table_RVA"type="unsignedint31"dfdl:inputValueCalc="{
>      unsignedint31(
>      fn:concat(./Hidden_Lookup_Table_bit0,
>      ./Hidden_Lookup_Table_bit1,
>      ./Hidden_Lookup_Table_bit2,
>      ./Hidden_Lookup_Table_bit3,
>      ./Hidden_Lookup_Table_bit4,
>      ./Hidden_Lookup_Table_bit5,
>      ./Hidden_Lookup_Table_bit6,
>      ./Hidden_Lookup_Table_bit7,
>      ./Hidden_Lookup_Table_bit8,
>      ./Hidden_Lookup_Table_bit9,
>      ./Hidden_Lookup_Table_bit10,
>      ./Hidden_Lookup_Table_bit11,
>      ./Hidden_Lookup_Table_bit12,
>      ./Hidden_Lookup_Table_bit13,
>      ./Hidden_Lookup_Table_bit14,
>      ./Hidden_Lookup_Table_bit15,
>      ./Hidden_Lookup_Table_bit16,
>      ./Hidden_Lookup_Table_bit17,
>      ./Hidden_Lookup_Table_bit18,
>      ./Hidden_Lookup_Table_bit19,
>      ./Hidden_Lookup_Table_bit20,
>      ./Hidden_Lookup_Table_bit21,
>      ./Hidden_Lookup_Table_bit22,
>      ./Hidden_Lookup_Table_bit23,
>      ./Hidden_Lookup_Table_bit24,
>      ./Hidden_Lookup_Table_bit25,
>      ./Hidden_Lookup_Table_bit26,
>      ./Hidden_Lookup_Table_bit27,
>      ./Hidden_Lookup_Table_bit28,
>      ./Hidden_Lookup_Table_bit29,
>      ./Hidden_Lookup_Table_bit30
>      ))
>      }"/>
> 
> <xs:groupname="hidden_Lookup_Table_Group">
> <xs:sequencedfdl:alignmentUnits="bits">
> <xs:elementname="Hidden_Lookup_Table_bit7"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit6"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit5"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit4"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit3"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit2"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit1"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit0"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit15"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit14"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit13"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit12"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit11"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit10"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit9"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit8"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit23"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit22"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit21"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit20"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit19"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit18"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit17"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit16"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit31"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit30"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit29"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit28"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit27"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit26"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit25"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit24"type="unsignedint1"
>              dfdl:outputValueCalc='{ . }'
> />
> </xs:sequence>
> </xs:group>
> 

Reply via email to