Continuing with the amazing stuff you can do with the eval() function: You can use it in a user interface binding to enable your form to programmatically control what the user sees.
As an exhibition of this capability, I'll give you the pertinent parts of an XML editor form that dynamically adjusts to XML structure and allows you to edit the content of any leaf nodes while giving you link buttons to allow you to drill deeper into element subtrees as well as a "back" button to go to the parent of any subtree whose leaves you may be editing. It starts with an XForms repeat, like this:
<xforms:repeat nodeset="eval(repeatexpr)" id="XMLEditor">
...
</xforms:repeat>
The repeat expression is computed by the form and is changed by user actions that drill deeper into the XML tree or go back to parent elements. The repeat expression will end with "/*" so that the controls in the repeat will show the children of whatever node the repeat expression selects before the "/*".
For simplicity, I've put the XML data to be edited as the first element of the instance that also manages the calculation of the repeat expression, but you could do this as two separate instances instead. Here's the instance structure I used in this example:
<xforms:instance id="data" xmlns="">
<data>
<Purchase-Order>
<Order-Details type="sequence">
<Item>
<Name/>
<Price/>
<Quantity/>
<Item-Cost type="currency" value="Price * Quantity"/>
</Item>
</Order-Details>
<Subtotal type="currency" value="sum(Order-Details/Item/Item-Cost)"/>
<Tax type="currency" value="Subtotal * 0.05"/>
<Total type="currency" value="Subtotal + Tax"/>
</Purchase-Order>
<expr></expr>
<scratchexpr/>
<firstelem></firstelem>
<path></path>
<repeatexpr></repeatexpr>
</data>
</xforms:instance>
The first element could be anything, but I used a "purchase order" data structure, so this form will magically morph into a purchase order editor. Further, it should now be clear why in the last blog I concentrated on data that carried its own formula calculations and data validation rules. If I replace the Purchase-Order element above with the loan calculation data below, then this same form will help calculate your monthly payment on a loan:
<Loan-Application label="ACME Used Car Loan Application">
<Start-Date type="date">*</Start-Date>
<Borrower>
<Name required="true">John Q. Public</Name>
<Address required="Name != ''"></Address>
<City required="Name != ''"></City>
<StatProv required="Name != ''" label="State/Province"/>
<PostalCode required="Name != ''"/>
<Employer required="../Principal > 20000"/>
</Borrower>
<Principal required="true" constraint="Principal > 0 and Principal <= 50000"></Principal>
<Duration required="true" constraint="Duration > 0 and Duration <= 84"></Duration>
<Interest-Rate constraint1="Interest-Rate > 0"
constraint2="Interest-Rate <= 5+floor(Duration div 12)"></Interest-Rate>
<rate hidden="true" value="Interest-Rate div 1200.0"/>
<Monthly-Payment type="currency"
relevant="Monthly-Payment > 0"
value="choose(rate > 0, 

Principal * rate div (1.0 - power(1.0 + rate, -Duration)), 

Principal div Duration)"
>856.07</Monthly-Payment>
<Total-Payout type="currency"
relevant="Monthly-Payment > 0"
value="Monthly-Payment * Duration"
>10272.90</Total-Payout>
</Loan-Application>
Within the repeat, we can use different kinds of form controls to be responsive to the identified types of data and also to the issue of whether something is an input or an output based on whether it has a computed value. Here are two examples at the XFDL+XForms level:
<field sid="INPUT_CURRENCY">
<xforms:input ref="self::node()[not(*) and not(@value) and @type='currency']">
<xforms:label><xforms:output value="choose(./@label, ./@label, concat(translate(local-name(.), '-_', ' '), ': '))"/></xforms:label>
<xforms:hint ref="./@hint"/>
<xforms:alert ref="./@alert"/>
</xforms:input>
<display compute="xformsenabled"/>
<format>
<datatype>currency</datatype>
</format>
</field>
<label sid="VALUE_CURRENCY">
<xforms:output ref="self::*[not(*) and @value and @type='currency']">
<xforms:label><xforms:output value="choose(./@label, ./@label, concat(translate(local-name(.), '-_', ' '), ': '))"/></xforms:label>
<xforms:hint ref="./@hint"/>
<xforms:alert ref="./@alert"/>
</xforms:output>
<border>on</border>
<display compute="xformsenabled=='on' and value != 'NaN' ? 'on' : 'off'"/>
<format>
<datatype>currency</datatype>
</format>
</label>
In the predicates of the form controls, "not (*)" ensures that these form controls are only relevant if the data node is a leaf that is to be filled with character content. The "value" attribute in the data provides a calculation formula, so that has been used to distinguish when to provide and input versus an output form control. The two examples above make relevant form controls for data elements annotated with a currency type attribute. Other form controls for checkboxes and dates can be created to bind to types like booleans and dates.
Next, let's look at how the repeat expression is computed:
<xforms:bind nodeset="firstelem" calculate="local-name(instance('data')/*[1])" />
<xforms:bind nodeset="path" calculate="concat(../firstelem, ../expr)" />
<xforms:bind nodeset="repeatexpr" calculate="concat(../path, '/*')" />
By design of this particular "magic morphing" (XML editor) form, the first element in the computed XPath expression is the first element of the instance. Then we compute the full path to the element whose children will become editable by the repeat and the form controls within the repeat. This is based on the "expr" data node that will be programatically manipulated. Because expr is initially empty in the instance data above, that means you will initially see the children of the first element of the instance, because the repeatexpr is calculated to the first element plus the initially empty "expr" plus "/*" to get the children.
OK, so how do we adjust what the XForms repeat presents to the user? Basically, we want to either add a child element name to drill down into a subtree or we want to subtract a child element name to go up a level. First, let's cover how to add an element, i.e. add a step to the location "path". Inside the repeat, each child element that is a subtree root (has children) gets an XForms trigger in a link style button. If you activate the trigger (press the button) then you drill down into the corresponding node. Here's what that looks like:
<xforms:trigger ref="self::node()[*]">
<xforms:label><xforms:output value="choose(./@label, concat(./@label, ' >>'), concat(translate(local-name(.), '-_', ' '), choose(*[1]/* or *[1]='', '', concat(' - ', *)), ' >>'))"/></xforms:label>
<xforms:hint ref="./@hint"/>
<xforms:alert ref="./@alert"/>
<xforms:action ev:event="DOMActivate">
<xforms:setvalue ref="instance('data')/expr"
value="concat(., '/', local-name(context()), 

choose(count(context()/../*[local-name(.)=local-name(context())]) = 1, '', 

concat('[', 1 + count(context()/preceding-sibling::*[local-name(.)=local-name(context())]), ']') 

) 

)"/>
<xforms:setindex repeat="XMLEditor" index="1"/>
<xforms:setfocus control="XMLEditor"/>
</xforms:action>
</xforms:trigger>
The trigger ref binds to a node that has children, as tested by the predicate "[*]". The label shows the name of the child element whose subtree you will drill into if you activate the trigger. The action sequence simply chucks a slash plus that name onto the end of the "expr" as a new step in the location path. This adds to the "path" which adds to the "repeatexpr" which updates the XForms repeat to show the children of that subtree root.
The trigger to go back up to a parent from a child is something that would live outside of the repeat because you only need one "back" button. It's actually a bit trickier because you can't get the last slash in order to lop off the last location step in the path. Fortunately, XPath lets you find the first occurrence of a substring, and XForms actions include a loop. So, the way I did this was to construct a new expression out of all the location steps in the old one, except the last, which was detectable by there being no more slashes. Here's what that looks like:
<xforms:trigger id="GoBack" ref="expr">
<xforms:label><<</xforms:label>
<xforms:hint>Go Back</xforms:hint>
<xforms:action ev:event="DOMActivate">
<xforms:setvalue ref="../scratchexpr" value="substring(../expr, 2)"/>
<xforms:setvalue ref="."/>
<xforms:action while="contains(../scratchexpr, '/')">
<xforms:setvalue ref="." value="concat(., '/', substring-before(../scratchexpr, '/'))"/>
<xforms:setvalue ref="../scratchexpr" value="substring-after(., '/')"/>
</xforms:action>
<xforms:setindex repeat="XMLEditor" index="1"/>
<xforms:setfocus control="XMLEditor"/>
</xforms:action>
</xforms:trigger>
The first setvalue copies the "expr" less the leading slash into the "scratchexpr". Then, we clear out the "expr" so we can build it up anew from the parts of the scratchexpr. Now, we execute while "scratchexpr" still contains a slash, so the loop stops short of copying the last location step from scratchexpr to expr. Once the processing is complete, then once again, the modifications made to expr, reverberate to "path" then to "repeatexpr" due to the XForms binds above, and so the XForms repeat updates to show and allow editing of the content of the parent element.
And that's it! Thanks to eval() used in combination with all other pre-existing features of XForms, you can make a form that edits any XML element data structure.