Last modified on 29 December 2007, at 11:35

XQuery/Parsing Query Strings

MotivationEdit

Normal http query strings use the ampersand (&) character in order to differentiate between different terms in a query string. However, because ampersands also are used as the start of entities within HTML and XML, this can make it difficult encoding parametric content into XML links, and it moreover makes it difficult to visually decipher query strings.

This program illustrates how to parse query strings using alternative delimiters (such as the semi-colon).

This program demonstrates some standard XQuery functions that are not part of the original XQuery specification but are required for precise web server XQuery functionality.

The functions are:

  • exist request:get-method()
  • exist util:unescape-uri()
  • exist request:get-query-string()
  • exist request:get-parameter()
  • exist request:get-parameter-names()

NamespaceEdit

 module namespace common = "http://www.metaphoricalweb.org/xmlns/common";

PlatformEdit

  • eXist

Parsing Query StringsEdit

common:get-parametersEdit

This base function retrieves the query string from the URI, parses the string using the given delimiter and creates an XML structure of the form

 <params>
   <param name="param1" value="paramval1"/>
   <param name="param2" value="paramval2"/>
 </params>


 declare function common:get-parameters($delimiter as xs:string) as node() {
    let $params := if (request:get-method() = "GET") then 
         let $query-string := util:unescape-uri(request:get-query-string(),"UTF-8")
         let $parsed-query := tokenize($query-string,$delimiter)
         return <params>
         {for $parsed-query-term in $parsed-query 
               let $parse-query-name := substring-before($parsed-query-term,"=")
               let $parse-query-value := substring-after($parsed-query-term,"=")
               return <param name="{$parse-query-name}" value="{$parse-query-value}"/>
               }
         </params>          
      else 
         <params>
             {for $name in request:get-parameter-names()
                   let $parse-query-name := $name
                   let $parse-query-value := request:get-parameter($name,"")                    
               return <param name="{$parse-query-name}" value="{$parse-query-value}"/>
               }
         </params>
   return $params
   };

common:get-parameterEdit

This function retrieves a sequence of string values corresponding to the values for a given parameter key given in the query string. Note that while typically there will be only one string in the sequence, if you have a query string of the form ?a=val1;b=val2;a=val3 then get-parameter("a","",";") will return ("val1","val3")

 declare function common:get-parameter($param-name as xs:string,$default-value as xs:string,$delimiter as xs:string) as xs:string* {
   let $params := common:get-parameters($delimiter)
   let $param-nodes := $params/param[@name=$param-name]
   let $param-values := 
      for $param-node in $param-nodes 
      return 
        if ($param-node/@value) 
        then string($param-node/@value) 
        else $default-value 
   return  $param-values
   };

common:get-parameter-namesEdit

This function retrieves the name of each query string key (once and only once per key).

 declare function common:get-parameter-names($delimiter as xs:string) as xs:string* {
   let $params := common:get-parameters($delimiter)
   for $param-name in distinct-values($params/param/@name)
   return $param-name
   };

Example ProgramEdit

Assumes query string of http://www.metaphoricalweb.org/?a=5;b=test;a=8;c=new+message

 let $msg := common:get-parameter("c","",";")
 return $msg
 

returns [Execute]

 new message   

 
  {
    for $key in common:get-parameter-names(";")
    return 
       <seq>{$key}:{common:get-parameter($key,"",";")}</seq>
  }
 

 

returns [Execute]

 
   <seq>a:5 8</seq>
   <seq>b:test</seq>
   <seq>c:new message</seq>
 </data



   let $seq1 := common:get-parameter("a",0,";")
   return  sum(for $n in $seq1 return number($n))

returns [Execute]

 13