Custom XPath functions: Difference between revisions

From W3C XForms Group Wiki (Public)
forms>Johnboyer
No edit summary
forms>Johnboyer
No edit summary
Line 26: Line 26:
This would be invoked in an XPath simply as foo(p, q)
This would be invoked in an XPath simply as foo(p, q)


Spec example: Something like [[decimal-round() function]]
Spec example: Something like [[decimal-string() function]]




Line 35: Line 35:
   <param name="places" type="number"/>
   <param name="places" type="number"/>


   <variable name="str" type="string" value="$num"/>
   <variable name="str" type="string" value="string($num)"/>
 
  <variable name="intpart" type="number" value="number(substring-before($str, '.'))"/>
 
  <variable name="fracstr" type="string" value="substring(substring-after($str, '.'), 0, $places)"/>
 
  <variable name="$fracpart" type="number" value="round(number($fracstr) / 10)"/>
 
    
    
...
...

Revision as of 23:12, 5 February 2008

Custom XPath Functions

It is possible to add XPath functions to an form using the processor's capabilities.

For example, a set of XForms actions could be given a function name and invoked from XPath.

The evaluation context for XPaths in the actions would be set to an implicit empty instance node, and the instance() function would not work for XPaths within an XForms function definition. This prevents function side-effects.

The function parameters would appears as XPath variables, and more variables could be declared.

Question: How should function namespace assignment work?


<function name="foo" type="number">
   <param name="p" type="number"/>

   <param name="q" type="number"/>
   
   <return value="$p+$q"/>
</function>  


This would be invoked in an XPath simply as foo(p, q)

Spec example: Something like decimal-string() function


<function name="decimal-round" type="string">
   <param name="num" type="number"/>

   <param name="places" type="number"/>

   <variable name="str" type="string" value="string($num)"/>

   <variable name="intpart" type="number" value="number(substring-before($str, '.'))"/>
   
   <variable name="fracstr" type="string" value="substring(substring-after($str, '.'), 0, $places)"/>

   <variable name="$fracpart" type="number" value="round(number($fracstr) / 10)"/>

   
...

   <return value="$result"/>
</function>  


Spec example: Need a sumproduct() function


<function name="sumproduct" type="number">
   <param name="p" type="nodeset"/>

   <param name="q" type="nodeset"/>

   <variable name="counter" type="number">1</variable>
   
   <variable name="accumulator" type="number">0</variable>

   <action if="count($p) = count($q)">
      <action while="$counter < count($p)">
         <setvalue ref="$accumulator" ". + ($p[$counter] * $q[$counter])"/>
         <setvalue ref="$counter" ". + 1"/>
      </action>
   </action>

   <return value="$accumulator"/>
</function>  

...

<output context="/purchaseOrder/items" value="sumproduct(item/price, item/quantity)"/>


The set of 'price' children of each 'item' comprise the first parameter. The set of 'quantity' children of each 'item' comprise the second parameter. For each pair of price and quantity elements under an item, the product is computed. The result is the accumulated sum of the products.