Understanding the XForms dependency-engine

Mark Birbeck's picture

A key component of an 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 forms.

To illustrate its use, let's take an instance that has two values which are summed to produce a third, and if the sum is greater than 10, the value is said to be invalid:

<xf:instance>
  <instanceData xmlns="">
    <a>4</a>
    <b>5</b>
    <c />
  </instanceData>
</xf:instance>

<xf:bind nodeset="c" calculate="../a + ../b" constraint=". &lt;= 10" />

Our calculate instruction says simply that the value of c is the result of summing a and b, which means that every time either a or b changes we want the calculation to be carried out again. Similarly, since the constraint is based on the value of c itself, then if it changes we need to perform the validity check again. This set of dependencies--the first saying that the value of c is dependent on the values of a and b, and the second saying that the validity of c is dependent on the value of c--is easy to create by parsing the XPath expressions in the bind statements. And once created, processing can be quite fast, since it is now possible to only perform calculations that are required by changes in the data.