Skip to content

Instantly share code, notes, and snippets.

@line-o
Last active May 1, 2021 19:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save line-o/e492401494a4e003bb01b7a2f884b027 to your computer and use it in GitHub Desktop.
Save line-o/e492401494a4e003bb01b7a2f884b027 to your computer and use it in GitHub Desktop.
Serialize a URL query string in XQuery
xquery version "3.1";
module namespace qs="http://line-o.de/ns/qs";
(:~
: Append nothing to names of parameters with multiple values
: ?single=v1&multi=v2&multi=v3
:)
declare function qs:serialize-default(
$parameters as map(xs:anyAtomicType, xs:anyAtomicType*)
) as xs:string? {
qs:serialize(
$parameters,
qs:serialize-parameter(?, ?, ()))
};
(:~
: Append [] to names of parameters with multiple values
: ?single=v1&multi[]=v2&multi[]=v3
:)
declare function qs:serialize-brackets(
$parameters as map(xs:anyAtomicType, xs:anyAtomicType*)
) as xs:string? {
qs:serialize(
$parameters,
qs:serialize-parameter(?, ?, '[]'))
};
(:~
: Commma separated values for parameters with multiple values
: ?single=v1&multi=v2,v3
:)
declare function qs:serialize-csv(
$parameters as map(xs:anyAtomicType, xs:anyAtomicType*)
) as xs:string? {
qs:serialize(
$parameters,
qs:serialize-parameter-csv#2)
};
declare function qs:serialize(
$parameters as map(xs:anyAtomicType, xs:anyAtomicType*),
$serializer as function(xs:anyAtomicType, xs:anyAtomicType*) as xs:string*
) as xs:string? {
if (map:size($parameters) eq 0)
then ()
else
concat("?",
map:for-each($parameters, $serializer)
=> string-join('&'))
};
declare function qs:serialize-parameter (
$raw-parameter-name as xs:anyAtomicType,
$values as xs:anyAtomicType*,
$appendix as xs:string?
) as xs:string* {
let $parameter-name := concat(
encode-for-uri($raw-parameter-name),
if (exists($values) and count($values)) then $appendix else ()
)
return
for-each($values,
qs:serialize-parameter-value($parameter-name, ?))
};
declare function qs:serialize-parameter-csv (
$raw-parameter-name as xs:anyAtomicType,
$values as xs:anyAtomicType*
) as xs:string* {
if (not(exists($values)))
then ()
else
concat(
encode-for-uri($raw-parameter-name),
'=',
for-each($values, encode-for-uri(?))
=> string-join(',')
)
};
declare function qs:serialize-parameter-value (
$parameter as xs:string, $value as xs:anyAtomicType
) as xs:string {
``[`{$parameter}`=`{encode-for-uri($value)}`]``
};
xquery version "3.1";
import module namespace qs="http://line-o.de/ns/qs";
qs:serialize-default(map{}),
qs:serialize-brackets(map{}),
qs:serialize-csv(map{}),
qs:serialize-default(map{ "a": ("b0","b1"), "b": "$=@#'" }),
qs:serialize-brackets(map{ "a": (xs:date("1970-01-01"),"b1"), "b": "$=@#'" }),
qs:serialize-csv(map{ "a": ("b0",3.14), "b": "$=@#'" }),
qs:serialize-default(map{ "a": ("b0","b1"), "c": () }),
qs:serialize-brackets(map{ "a": ("b0","b1"), "c": () }),
qs:serialize-csv(map{ "a": ("b0","b1"), "c": () })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment