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>

Reply via email to