Oh. I think I get it. You can't write:
<xs:element name='color' type='xs:string' dfdl:inputValueCalc="{
doc('Colors.xml')//row[number eq ../Hidden_color_number]/symbol}" />
because the ../ in the relative path would be interpreted relative to a place
in the colors.xml data, and there isn't even a common relative path root to
walk up to since that is its own document.
So I guess you would have to have dfdl:newVariableInstance to bind a variable
and use it there. So this is one more up-vote for that feature.
I see you are trying to formulate an XPath-like way of doing numeric to
symbolic (and back for unparsing) lookup tables.
It is feasible to extent DFDL/Daffodil to implement the doc(....) function -
read some XML and construct the corresponding DFDL infoset with it, then apply
the rest of the path expression to that.
But in addition after that, you have a predicate with a boolean expression in
it. DFDL doesn't have that either. Just numeric indexing. Using just numeric
indexing this could work for parsing:
doc('Colors.xml')//row[../Hidden_color_number + 1]/symbol
That would run O(1) time.
but the reverse lookup from a string value to it's equivalent number can't be
expressed in DFDL today either unfortunately.
We really want ability to create a hash-map for O(1) translation of a string to
an integer, but we don't want complexity that comes from allowing arbitrary
XPath-style predicate expressions.
And that would be why the proposal on the Daffodil Wiki right now doesn't
suggest using XPath-stuff, but just a set of annotations on enum definitions
from which a lookup table can be built, and then custom XPath-style functions
for doing forward and backward lookups on the table.
Admittedly it's not fully baked yet:
https://cwiki.apache.org/confluence/display/DAFFODIL/Proposal%3A+Features+to+Support+Table-Lookup
________________________________
From: Costello, Roger L. <[email protected]>
Sent: Monday, November 5, 2018 1:01:04 PM
To: [email protected]
Subject: RE: Can I create a local variable in DFDL?
Hi Mike,
* instead of your
*
* <xsl:variable name="Hidden_color_number"
select="../Hidden_color_number"/>
*
* write
*
* <xs:element name="HCN" type="xs:int"
* dfdl:inputValueCalc='{ ../Hidden_color_number }' />
I am unclear how that element can be used in my element declaration:
<xs:element name='color' type='xs:string' dfdl:inputValueCalc="{
doc('Colors.xml')//row[number eq xs:string(?????)]/symbol}" />
The color element declaration uses the XPath doc() function to reference a
separate document (Colors.xml), navigates through that XML document for a <row>
element with a child <number> element whose value matches the value of
Hidden_color_number; once found, it fetches the value of the <symbol> element
within <row>. That is, I have a separate document that maps numeric value to
symbolic value:
<Colors>
<row>
<number>0</number>
<symbol>red</symbol>
</row>
<row>
<number>1</number>
<symbol>blue</symbol>
</row>
<row>
<number>2</number>
<symbol>green</symbol>
</row>
<row>
<number>3</number>
<symbol>yellow</symbol>
</row>
</Colors>
How to use the HCN element that you described in my XPath expression?
/Roger
From: Mike Beckerle <[email protected]>
Sent: Monday, November 5, 2018 12:17 PM
To: [email protected]
Subject: Re: Can I create a local variable in DFDL?
There's good news, and bad news.
The good news: The dfdl:newVariableInstance is the way this is supposed to work.
It creates a "stack allocated" variable. The variable and its type must be
declared at top level, then entering a scope having newVariableInstance
referencing that var creates a local one which is temporary, until the
parser/unparser leaves that scope.
The bad news: Alas.... Daffodil has not yet implemented newVariableInstance.
The good news: One can always achieve (for parsing anyway) the same thing by an
element having dfdl:inputValueCalc.
So below, instead of your
<xsl:variable name="Hidden_color_number"
select="../Hidden_color_number"/>
write
<xs:element name="HCN" type="xs:int"
dfdl:inputValueCalc='{ ../Hidden_color_number }' />
Instead of a variable you get an element, in this case "HCN", with a known and
fixed relative path, which is defined in terms of the expression which contains
the varying relative path that you are trying to keep out of your expression.
The existence of this work-around is one of the reasons we haven't gotten
around to dfdl:newVariableInstance as of yet.
This is one of the softer areas of the DFDL spec. This workaround works, but
only for parsing, since inputValueCalc elements aren't evaluated when
unparsing. So really we do need newVariableInstance to work; however, there are
shortcoming there as well having to do with array instances.
________________________________
From: Costello, Roger L. <[email protected]<mailto:[email protected]>>
Sent: Monday, November 5, 2018 11:44 AM
To: [email protected]<mailto:[email protected]>
Subject: Can I create a local variable in DFDL?
Hello DFDL community!
I want to create a local variable; is that possible in DFDL?
For example, I would like to create a variable to hold the value of a hidden
element and then use that variable in an inputValueCalc expression. Below I
show the idea: I create a variable named Hidden_color_number and then use that
variable in the inputValueCalc expression. I show creating an XSLT variable,
which is obviously not correct. Is there a way to do this in DFDL? /Roger
<xs:element name="enum-test">
<xs:complexType>
<xs:sequence>
<xs:sequence dfdl:hiddenGroupRef="hidden_Color_Group" />
<xsl:variable name="Hidden_color_number"
select="../Hidden_color_number"/>
<xs:element name='color' type='xs:string' dfdl:inputValueCalc="{
doc('Colors.xml')//row[number eq
xs:string($Hidden_color_number)]/symbol}" />
</xs:sequence>
</xs:complexType>
</xs:element>