XQuery/Adder

MotivationEdit

We would like to create a simple XQuery that takes two arguments and returns the the sum of the two numbers.

Example Program Using URL Parameters (HTTP GET)Edit

xquery version "1.0";
declare namespace request="http://exist-db.org/xquery/request";
declare namespace xs="http://www.w3.org/2001/XMLSchema";

(: get the parameters from the URL :)
let $arg1 := xs:integer(request:get-parameter("arg1", "1"))
let $arg2 := xs:integer(request:get-parameter("arg2", "5"))

return
<results>
    <sum>{$arg1+$arg2}</sum>
</results>

Call this like ($hostname)/adder.xq?arg1=123&arg2=456.

Execute

ResultsEdit

<results>
   <sum>579</sum>
</results>

Accumulating AdderEdit

To make this into an interactive application, we can extend the script to create an XHTML document containing a Form.

The script computes the new sum from the URL parameters (if any) and returns a minimal XHTML document containing a Form which both reports the sum and prompts for new inputs. Note the embedded XQuery expressions (in curly braces) which interpolates the computed values into the created XML element. The state of the computation, the value of the accumulator, is retained in a hidden input in the form.

xquery version "1.0";
declare namespace request="http://exist-db.org/xquery/request";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare option exist:serialize "method=xhtml media-type=text/html indent=yes";

let $sum := xs:integer(request:get-parameter("sum",0))
let $number := xs:integer(request:get-parameter("number","0"))
let $newSum := $sum + $number
return
<html>
  <head><title>Accumulating Adder</title></head>
  <body>
    <h1>Accumulating Adder</h1>
    <form>
     {$newSum} + <input type="text" name="number"  value="{$number}" />     
      <input type="hidden" name="sum" value="{$newSum}"/>  
    </form>
  </body>
</html>

Execute

Clearing the accumulatorEdit

To support the operation of clearing the accumulator, we can add a couple of submit buttons to the form. The presence of the 'Clear' action is used to set the inputs to zero.

xquery version "1.0";
declare namespace request="http://exist-db.org/xquery/request";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare option exist:serialize "method=xhtml media-type=text/html indent=yes";

let $action := request:get-parameter("action","")
let $sum :=
    if ($action= "clear")
    then 0 
    else xs:integer(request:get-parameter("sum",0))
let $number :=
    if ($action = "clear")
    then 0
    else xs:integer(request:get-parameter("number"," "))
let $newSum := $sum + $number
return
<html>
  <head><title>Accumulating Adder</title></head>
  <body>
    <h1>Accumulating Adder</h1>
    <form>
      {$newSum} + <input type="text" name="number" value="{$number}" />   
      <input type="hidden" name="sum" value="{$newSum}"/>
      <input type="submit" name="action"  value="add"/>
      <input type="submit" name="action"  value="clear"/>
    </form>
  </body>
</html>

Execute

Example Using Session VariablesEdit

An alternative way of holding the state of this computation is in session variables. The session module in eXist provides the necessary functions.

xquery version "1.0";

declare namespace request="http://exist-db.org/xquery/request";
declare namespace session="http://exist-db.org/xquery/session";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare option exist:serialize "method=xhtml media-type=text/html indent=yes";

let $sum  := if (exists(session:get-attribute("sum")))
             then session:get-attribute("sum")
             else 0
let $action := request:get-parameter("action","")
let $sum :=
    if ( $action= "clear")
    then 0 
    else $sum
let $number :=
    if ($action = "clear")
    then 0
    else xs:integer(request:get-parameter("number","0"))
let $newSum := $sum + $number
let $s := session:set-attribute("sum",$newSum)
return
<html>
  <head><title>Accumulating Adder</title></head>
  <body>
    <h1>Accumulating Adder</h1>
    <form>
       {$newSum} + <input   type="text" name="number"   value="{$number}" />   
      <input type="submit" name="action"  value="add"/>
      <input type="submit" name="action"  value="clear"/>
    </form>
  </body>
</html>

Execute

Sample Using HTTP POSTEdit

xquery version "1.0";
declare namespace request="http://exist-db.org/xquery/request";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare option exist:serialize "method=xml media-type=text/xml indent=yes omit-xml-declaration=no";

(: get the parameters from the URL :)
(: call this like ($hostname)/adder.xq?arg1=123&arg2=456 :)
let $posted-data := request:get-data()
let $arg1 := $posted-data//arg1/text()
let $arg2 := $posted-data//arg2/text()

return
<results>
    <sum>{$arg1+$arg2}</sum>
</results>
Last modified on 21 December 2010, at 12:57