This suggestion got me to a solution that works great. Thank you!

dfdl:occursIndex() was my missing link I needed.  

 

From: Mike Beckerle <mbecke...@apache.org> 
Sent: Tuesday, October 22, 2024 12:36 PM
To: users@daffodil.apache.org
Subject: Re: revisit of parsing dynamic types?

 

The trick here is that in one pass you have to have a choice that selects a 
branch based on the type string in the header.

 

Here's the idea, many details omitted, but I think you should get the gist:

 

<!--

 Each record contains a vector of fields, the number of fields is the number of 
entries in the field descriptor array.

The name and the type are from the field descriptor array entry corresponding 
to the field position. 

 --> 

<element name="record">

    <complexType>

      <sequence>

         <element name="field"  minOccurs="1" maxOccurs="200"

              dfdl:occursCountKind="expression" dfdl:occursCount="{ 
fn:count(../../fieldDescriptorArray/Field) }">

            <complexType>

              <sequence dfdl:separator="%NL;">

                <element name="name" type="xs:string" dfdl:inputValueCalc='{ 
pathToFieldArray[dfdl:occursIndex()]/name }'/>

                 <!--

                   Here we use a choice where we choose a branch based on the 
name of the type

                    in the field descriptor

                  -->

                <element name="value">

                   <complexType>

                <choice dfdl:choiceDispatchKey='{ path to field array 
[dfdl:occursIndex()]/type }' >

                  <element name="s" type="xs:string" 
dfdl:choiceBranchKey="string" 

                        dfdl:lengthKind="explicit" dfdl:length='{ 
pathToFieldArray[dfdl:occursIndex]/length }'/>

                  <element name="b" type="xs:boolean" 
dfdl:choiceBranchKey="boolean"

                        dfdl:lengthKind="explicit" dfdl:length="1" />

                    ....

                </choice>

                  </complexType>

                 </element>

             </sequence>     

          </complexType>

        </element>

      </sequence>

    </compllexType>

</element>

 

So the data you will get out looks like:

 

<record>

  <field>

     <name>station-name</name>

     <value><s>Van Dorn Street</s></value>

  </field>

  <field>

     <name>line</name>

     <value><s>blue</s></value>

  </field>

  <field>

      <name>isActive</name>

      <value><b>true</b></value>

  </field>

</record>

 

When parsing, the above schema will enforce that if the header says "boolean" 
type, that the data must parse as

a boolean, i.e., the types are required to match between header and data. 

 

There is no way in DFDL to generate element names dynamically. That requires 
the 2-pass approach. 

The above is the best you can do in one pass. 

 

Note that an XSLT (which chatGPT can write for you) can translate this XML into:

 

<record>

  <station-name>Van Dorn Street</station-name>

  <line>blue</line>

  <isActive>true</isActive>

</record>      

 

or even:

 

<record stationName="Van Dorn Street" line="blue" isActive="true"/>

 

I hope that helps.

 

 

 

On Tue, Oct 22, 2024 at 9:10 AM Mark Kozak <mark.ko...@adeptus-cs.com> wrote:

Thank you Mike,

 

I have had some success implementing the two pass approach, but that will 
require some major restructuring of the parent project. So a single pass 
approach is still needed in at least the short term. Any help getting that to 
work will be very helpful.

 

Thanks again,

Mark Kozak

 

From: Mike Beckerle <mbecke...@apache.org <mailto:mbecke...@apache.org> > 
Sent: Friday, October 18, 2024 7:15 PM
To: users@daffodil.apache.org <mailto:users@daffodil.apache.org> 
Subject: Re: revisit of parsing dynamic types?

 

Sorry this got buried. I'll be back tuesday and will try to respond then if 
nobody else already has. 

 

On Tue, Oct 8, 2024 at 2:42 PM Mark Kozak <mark.ko...@adeptus-cs.com 
<mailto:mark.ko...@adeptus-cs.com> > wrote:

Hello daffodil community. 

 

I am working on project that could be implemented by a schema similar to what 
was described in lists.apache.org/thread/1y9rl31q4hcnmtylz1dd0gdgrxty4onf 
<https://lists.apache.org/thread/1y9rl31q4hcnmtylz1dd0gdgrxty4onf> . But I 
can't figure out how to iterate over the attribute types while looking back in 
the header. 

 

In the referenced example:

 

<record>
<field><s>blue</s></field>
<field><b>true</b></field>
</record>


How do you get s and the b? I know we can look back it ../.. But how do I go 
back down multiple paths to first get the s and then the b?

 

Thank you for any enlightenment.

 

 

Mark Kozak

Director of Engineering

Adeptus Cyber Solutions

Adeptus-CS.com

 

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to