Rationale
Orbeon Forms supports declaring variables which look and behave very much like XSLT variables. Variables are extremely useful, for example to avoid repeating long XPath expressions, or to give an XPath expression unambiguous access to data computed in enclosing
<xforms:group> or
<xforms:repeat> elements.
The <xxforms:variable> element
You define variables with the extension element
<xxforms:variable>. The element supports the following attributes:
| name | mandatory | Name of the variable. |
| as | optional
| Type of the variable. This is ignored as of 2009-09, but can be used for documentation purposes.
|
| model | optional | Contributes to the variable's single-node binding.
|
| context | optional | Contributes to the variable's single-node binding. |
| ref | optional | Contributes to the variable's single-node binding. |
| bind | optional | Contributes to the variable's single-node binding. |
| select | optional | XPath 2.0 expression determining the value of the variable. The expression is evaluated in the element's single-node binding if present, otherwise in the context of its parent. If the attribute is omitted, the text content of the <xxforms:variable> element is used as the value. |
NOTE: You can also use <exforms:variable> in the eXforms namespace. Variables within <xforms:model>
Under the
<xforms:model> element, the following rules apply:
- Variables are supported directly under the <xforms:model> element.
- Model variables are evaluated in the order in which they appear in the model.
- All model variables are visible to other model elements such as <xforms:bind> or <xforms:submission>.
- Model variables are also visible from XPath expression outside of models whenever that model is in scope.
<xhtml:head>
<xforms:model id="my-model">
<xforms:instance id="my-instance">...</xforms:instance>
<xxforms:variable name="mine" select="."/>
</xforms:model>
<xforms:model id="her-model">
<xforms:instance id="her-instance">...</xforms:instance>
<xxforms:variable name="hers" select="instance('her-instance')"/>
</xforms:model>
</xhtml:head>
<xhtml:body>
<!-- $mine is visible from here, but not $hers -->
<xforms:output value="$mine">
<xforms:label>My stuff:</xforms:label>
</xforms:output>
<xforms:group model="her-model">
<!-- $hers is visible from here, but not $mine -->
<xforms:output value="$hers">
<xforms:label>Her stuff:</xforms:label>
</xforms:output>
</xforms:group>
</xhtml:body>
Variables outside <xforms:model>
Outside of models, the following rules apply:
- Variables are supported anywhere XForms controls are allowed.
- A given variable is visible to any XPath expression on a following sibling element or on a following sibling element's descendant element.
<xhtml:body>
<!-- Variable pointing to the default instance's root element -->
<xxforms:variable name="instance" select="."/>
<!-- variable pointing to all the item children -->
<!-- It uses the variable declared above -->
<xxforms:variable name="items" select="$instance/item"/>
<!-- The code below uses the variables in scope -->
<xforms:repeat nodeset="$items" id="items-repeat">
<xxforms:variable name="current-item" select="."/>
<xxforms:variable name="current-position" select="position()"/>
<xforms:output id="my-count" ref="$current-item/value">
<xforms:label value="concat($current-item/label, ':')"/>
<xforms:setvalue ev:event="my-event" ref="$current-item/value" value="count($items) + $current-position"/>
</xforms:output>
</xforms:repeat>
</xhtml:body>
Variables within <xforms:action>
Variables are allowed within
<xforms:action> elements, whether those elements are used within models or controls.
<xforms:model>
<xforms:instance>
<instance>
<foo>42</foo>
<bar>43</bar>
</instance>
</xforms:instance>
<!-- These variables are defined within the model -->
<xxforms:variable name="foo" select="foo"/>
<xxforms:variable name="bar" select="bar"/>
</xforms:model>
...
<xforms:group>
<!-- This variable is defined within the group control and has access to the in-scope model variables -->
<xxforms:variable name="sum" select="$foo + $bar"/>
<xforms:group>
<xforms:action ev:event="my-event">
<!-- This action has access to all variables in scope -->
<xforms:setvalue ref="sum" value="$sum"/>
<!-- This variable is defined within the action and has access to all the variables in scope -->
<xxforms:variable name="difference" select="$foo - $bar"/>
<xforms:setvalue ref="difference" value="$difference"/>
</xforms:action>
</xforms:group>
</xforms:group>
The <xxforms:sequence> element
Like in XSLT, you can nest an
<xxforms:sequence> element within
<xxforms:variable>. This allows you to decouple the variable definition (name) from its evaluation:
<xxforms:variable name="sum">
<xxforms:sequence select="$foo + $bar"/>
</xxforms:variable>
This is particularly useful for XBL component implementors, where this can be used in combination with the
xxbl:scope attribute:
<xxforms:variable name="result" as="node()?">
<xxforms:sequence select="." xxbl:scope="outer"/>
</xxforms:variable>
Single-node attributes may be used on the <xxforms:sequence> element.
Current limitations
As of 2009-09, the implementation has the following limitations:
- <xxforms:variable> element:
- The as attribute is ignored but can be used for documentation purposes.
- Cannot be used within XForms leaf controls such as <xforms:input>, including within nested items or itemsets (except within <xforms:action> elements, where they are allowed).
- Cannot be used within nested model elements, including <xforms:bind> or <xforms:submission> (except within <xforms:action> elements, where they are allowed).
- <xxforms:sequence> element:
- Only one <xxforms:sequence> element is currently allowed as child of <xxforms:variable>.
- When used, single-node attributes may not be used on the parent <xxforms:variable> element.