Hi Mike,

I created a simple DFDL schema which shows the problem:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:dfdl=http://www.ogf.org/dfdl/dfdl-1.0/ xmlns:f="function" 
xmlns:fn=http://www.w3.org/2005/xpath-functions 
xmlns:xs=http://www.w3.org/2001/XMLSchema>
    <xs:include schemaLocation="default-dfdl-properties/defaults.dfdl.xsd"/>
    <xs:annotation>
        <xs:appinfo source=http://www.ogf.org/dfdl/>
            <dfdl:format ref="default-dfdl-properties" 
emptyValueDelimiterPolicy="none"/>
        </xs:appinfo>
    </xs:annotation>
    <xs:element name="Document">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="initial_word"/>
                <xs:element ref="row" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="initial_word">
        <xs:complexType>
            <xs:sequence>
                <xs:sequence dfdl:hiddenGroupRef="hidden-message-length"/>
                <xs:element name="E1" type="xs:string"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="row">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="E2" type="xs:string"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:group name="hidden-message-length">
        <xs:sequence>
            <xs:element name="hidden" type="xs:integer"
                dfdl:outputValueCalc="{
                if (fn:exists(/Document/foo)) then 
fn:count(/Document/row)+fn:count(/Document/foo)+1
                else fn:count(/Document/row)+1
                }"
            />
        </xs:sequence>
    </xs:group>
</xs:schema>



From: Mike Beckerle <mbecke...@apache.org>
Sent: Thursday, January 4, 2024 8:57 AM
To: users@daffodil.apache.org
Subject: [EXT] Re: How to count the number of child elements of the root 
element?

Yes, could be a bug. But that aspect of daffodil is quite well tested so I'm 
surprised at this. Can you send your Document element declaration showing the 3 
children row, initialWord and foo ? If the schema is confidential you can send

Yes, could be a bug. But that aspect of daffodil is quite well tested so I'm 
surprised at this.

Can you send your Document element declaration showing the 3 children row, 
initialWord and foo ?

If the schema is confidential you can send me an encrypted email to my Owl 
email address.

On Thu, Jan 4, 2024 at 8:45 AM Roger L Costello 
<coste...@mitre.org<mailto:coste...@mitre.org>> wrote:
Hi Mike,


  *   Normally that message would also tell you what the possibilities for 
children of Document are (assuming there are some children of Document). Do you 
also get that in the error message? I think it should be telling you your 
choices are {}row

Yes, that’s correct. The error messsage told me my choices are {}row and 
{}initial_word


  *   Is foo a local element declaration with no namespace (meaning schema's 
elementFormDefault='unqualified')?

Correct.


  *   Assuming we figure out why it can't find your foo element decl, you are 
on the right track with the if (fn:exists(... stuff.

Great. Then there is a bug in Daffodil, rigfht?

/Roger

From: Mike Beckerle <mbecke...@apache.org<mailto:mbecke...@apache.org>>
Sent: Thursday, January 4, 2024 8:27 AM
To: users@daffodil.apache.org<mailto:users@daffodil.apache.org>
Subject: [EXT] Re: How to count the number of child elements of the root 
element?

There could be a bug, but we don't have enough here to reproduce it. That error 
message: No element corresponding to step {}foo, means that to Daffodil, the 
path /Document/foo doesn't make sense because Daffodil cannot find the element
ZjQcmQRYFpfptBannerStart
annerEnd
There could be a bug, but we don't have enough here to reproduce it.

That error message: No element corresponding to step {}foo, means that to 
Daffodil, the path /Document/foo doesn't make sense because Daffodil cannot 
find the element declaration for foo as a child element declaration of the 
element declaration for Document.  The "{}" would contain a namespace URI if 
the foo element it was seeking was in a namespace. It is seeking a no-namespace 
child element decl for foo.

Normally that message would also tell you what the possibilities for children 
of Document are (assuming there are some children of Document). Do you also get 
that in the error message? I think it should be telling you your choices are 
{}row and perhaps others.

Is foo a local element declaration with no namespace (meaning schema's 
elementFormDefault='unqualified')?

Assuming we figure out why it can't find your foo element decl, you are on the 
right track with the if (fn:exists(... stuff.

In DFDL expressions, you can't just issue an expression as a query and get back 
"empty node set" to indicate that the expression wasn't meaningful. The 
expression must (a) be type-correct vis a vis the schema (b) cannot ask for 
counts, values, null-ness, etc. of things that are non-existing. This allows us 
to detect most errors at schema compilation time, not run time. It also allows 
the run-time to be very efficient with almost no runtime checking required.

On Thu, Jan 4, 2024 at 7:09 AM Roger L Costello 
<coste...@mitre.org<mailto:coste...@mitre.org>> wrote:
Suppose in the future there will be a foo element. So, I first test for the 
existence of foo:

{
    if (fn:exists(/Document/foo)) then 
fn:count(/Document/row)+fn:count(/Document/foo)+1
    else fn:count(/Document/row)+1
}

Daffodil gives the same error message: No element corresponding to step {}foo 
found.

Eek! That seems like a bug in Daffodil. Or a bug in the DFDL specification. Or 
both. Yes?

/Roger

From: Roger L Costello <coste...@mitre.org<mailto:coste...@mitre.org>>
Sent: Thursday, January 4, 2024 6:49 AM
To: users@daffodil.apache.org<mailto:users@daffodil.apache.org>
Subject: Re: How to count the number of child elements of the root element?

Mike said:


  *   { fn:count(/Document/row) + 1 } should give the value you want.

Question: Suppose I call fn:count on a non-existent foo element:

{fn:count(/Document/row)+fn:count(/Document/foo)+1}

I would expect fn:count(/Document/foo) to return 0 since there are no foo 
elements. But it doesn’t. Daffodil generates an error. Why is that?

/Roger

From: Mike Beckerle <mbecke...@apache.org<mailto:mbecke...@apache.org>>
Sent: Tuesday, January 2, 2024 8:32 AM
To: users@daffodil.apache.org<mailto:users@daffodil.apache.org>
Subject: [EXT] Re: How to count the number of child elements of the root 
element?

DFDL's count function does not operate on any "node set", but on specific named 
array elements only. In your case, the array is the row element, so { fn: 
count(/Document/row) + 1 } should give the value you want. On Wed, Dec 27,
DFDL's count function does not operate on any "node set", but on specific named 
array elements only.

In your case, the array is the row element, so { fn:count(/Document/row) + 1 } 
should give the value you want.

On Wed, Dec 27, 2023 at 8:44 AM Roger L Costello 
<coste...@mitre.org<mailto:coste...@mitre.org>> wrote:
Hi Folks,

My input file has a field containing the number of “words” in the file, where 
the “words” are the child elements of the root element. Here’s the XML that 
parsing produces:

<Document>
    <initial_word>
        <message_length>3</message_length>
    </initial_word>
    <row>...</row>
    <row>...</row>
</Document>

The message_length is the initial_word + number of <row> elements, i.e., 1 + 2 
= 3

I would like to hide message_length because it provides no meaningful 
information in the XML (after all, if you want to know the message length 
simply count the child elements of <Document>).

To hide message_length, I will need a hidden group in my DFDL schema:

    <xs:group name="hidden-MESSAGE_LENGTH ">
        <xs:sequence>
            <xs:element name="hidden" type="unsignedint3" 
dfdl:outputValueCalc="{????}"/>
        </xs:sequence>
    </xs:group>

The challenge that I am having is what XPath to use in dfdl:outputValueCalc. 
Initially, I used this:

dfdl:outputValueCalc="{fn:count(/Document/*)}

Daffodil complained: Wildcard * is not supported.

Then I tried this:

dfdl:outputValueCalc="{fn:count(../following-sibling::row)+1}

Daffodil complained: following-sibling axis is not supported.

Eek!

I don’t know what else to try. Any suggestions?

/Roger

Reply via email to