Understanding the XForms dependency-engine
A key component of any XForms processor is the
dependency-engine. The idea is pretty straightforward, and will be familiar to anyone who has used a spreadsheet; if some item has its value set by a calculated expression that contains references to other items, then when any of those items change, the first item must be recalculated.
It's not necessary to understand the dependency-engine when programming XForms, but having some familiarity with how it works may help when structuring your forms.
To illustrate its use, let's take an XML instance that has two values which are summed to produce a third:
<xf:model>
<xf:instance>
<instanceData xmlns="">
<c></c>
</instanceData>
</xf:instance>
<xf:bind nodeset="c" calculate="../a + ../b"></xf:bind>
</xf:model>
Our
calculate instruction says simply that the value of
c is the result of summing
a and
b. Just as with a spreadsheet, this means that every time either
a or
b changes, the XForms processor needs to carry out the calculation again.
Dependencies like this are easy to create by parsing the XPath expressions in the bind statements. And once created, processing can be quite fast, since the only calculations that need to be run are those required by
changes in the data. In this case, the processor will only ever need to recalculate
c if
a or
b changes, and not otherwise.
To see how this works let's add a couple of input controls so that you can change the values of
a and
b:
<xf:input ref="a">
<xf:label>a:</xf:label>
</xf:input>
<xf:input ref="b">
<xf:label>b:</xf:label>
</xf:input>
We also need an output control so that you can see the result:
<xf:output ref="c">
<xf:label>c:</xf:label>
</xf:output>
The result form is here -- try changing the values to be sure that things happen how you'd expect them to:
The key thing to stress here is that just as with spreadsheets, the changes to
c are happening automatically, without the form author having to program anything more than the calculation.