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