XQuery/Adder

From Wikibooks, open books for an open world
Jump to navigation Jump to search

Motivation[edit | edit source]

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

Example Program Using URL Parameters (HTTP GET)[edit | edit source]

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 http://kitwallace.co.uk/xqbook/interaction/adder.xq?arg1=123&arg2=456.

Results[edit | edit source]

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

Accumulating Adder[edit | edit source]

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>

Try this http://kitwallace.co.uk/xqbook/interaction/adder2.xq

Clearing the accumulator[edit | edit source]

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",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}"/>
      <input type="submit" name="action"  value="add"/>
      <input type="submit" name="action"  value="clear"/>
    </form>
  </body>
</html>

Try this with http://kitwallace.co.uk/xqbook/interaction/adder3.xq

Example Using Session Variables[edit | edit source]

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>

Try this with http://kitwallace.co.uk/xqbook/interaction/adder4.xq

Sample Using HTTP POST[edit | edit source]

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 :)

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>