I've been working on DAFFODIL-2429, which is adding a "direction" property to defineVariable. I believe I have most of the implementation in place. It is primarily implemented as follows:
dfdl:defineVariable has a property "dfdlx:direction" which is an enumeration with the following values: "parseOnly", "unparseOnly", or "both" which is the default value. When we are compiling the schema and are about to generate a SetVariabler or NewVariableInstance parser/unparser, we check the "direction" property and if the direction does not match (ie. Creating a SetVariable parser when the variable in question is "unparseOnly") we instead create a NadaParser. I'm not 100% sure that this is necessarily the correct approach, but it doesn't break any existing tests. Speaking of tests, I am attempting to create a test to demonstrate this feature based off the pull request mentioned in the bug ticket: https://github.com/DFDLSchemas/PCAP/pull/10 The schema for my test is as follows: <dfdl:defineVariable name="remainingAddr" type="xs:string" dfdlx:direction="unparseOnly" /> <xs:element name="root"> <xs:complexType> <xs:sequence> <xs:annotation> <xs:appinfo source="http://www.ogf.org/dfdl/"> <dfdl:newVariableInstance ref="ex:remainingAddr" defaultValue="{ ex:IPsrc }" /> </xs:appinfo> </xs:annotation> <xs:element name="byte1" type="xs:unsignedByte" dfdl:outputValueCalc="{ xs:unsignedByte(fn:substring-before($ex:remainingAddr, '.')) }" /> <xs:sequence> <xs:annotation> <xs:appinfo source="http://www.ogf.org/dfdl/"> <dfdl:newVariableInstance ref="ex:remainingAddr" defaultValue="{ fn:substring-after($ex:remainingAddr, '.') }" /> </xs:appinfo> </xs:annotation> <xs:element name="byte2" type="xs:unsignedByte" dfdl:outputValueCalc="{ xs:unsignedByte(fn:substring-before($ex:remainingAddr, '.')) }" /> <xs:sequence> <xs:annotation> <xs:appinfo source="http://www.ogf.org/dfdl/"> <dfdl:newVariableInstance ref="ex:remainingAddr" defaultValue="{ fn:substring-after($ex:remainingAddr, '.') }" /> </xs:appinfo> </xs:annotation> <xs:element name="byte3" type="xs:unsignedByte" dfdl:outputValueCalc="{ xs:unsignedByte(fn:substring-before($ex:remainingAddr, '.')) }" /> <xs:sequence> <xs:annotation> <xs:appinfo source="http://www.ogf.org/dfdl/"> <dfdl:newVariableInstance ref="ex:remainingAddr" defaultValue="{ fn:substring-after($ex:remainingAddr, '.') }" /> </xs:appinfo> </xs:annotation> <xs:element name="byte4" type="xs:unsignedByte" dfdl:outputValueCalc="{ xs:unsignedByte(fn:substring-before($ex:remainingAddr, '.')) }" /> </xs:sequence> </xs:sequence> </xs:sequence> <xs:element name="IPsrc" type="xs:string" dfdl:lengthKind="explicit" dfdl:length="7" dfdl:inputValueCalc="{ fn:concat(../ex:byte1, '.', ../ex:byte2, '.', ../ex:byte3, '.', ../ex:byte4) }" /> </xs:sequence> </xs:complexType> </xs:element> This is pretty much a direct copy of the schema in the pull request that on parse will parse 4 bytes and then use an inputValueCalc to combine the 4 bytes into an IP address. On unparse outputValueCalc's is used to pull apart the combined address back into the individual bytes. During unparse, the byte* elements do a forward reference to IPsrc and this seems to be causing a problem in my test. I'm getting a "Unparse Error: Expression Evaluation Error: Child element {http://example.com}IPsrc does not exist". So, my question regarding the test is should this work or am I missing something that is preventing this forward reference from working during unparsing? Josh Adams