Skip to content

Instantly share code, notes, and snippets.

@joewiz
Forked from xquery/data-composition.xqy
Last active June 4, 2019 15:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joewiz/675668c3f96667b8c307fda492aa5cf9 to your computer and use it in GitHub Desktop.
Save joewiz/675668c3f96667b8c307fda492aa5cf9 to your computer and use it in GitHub Desktop.
This works in BaseX and Saxon, but eXist returns an error: `exerr:ERROR cannot convert function(*)('') to a node set [at line 59, column 15]`
xquery version "3.0";
(: discovered via https://twitter.com/_james_fuller/status/1087706435176288257, updated with HTTP URL for data.xq :)
(: the power of algebraic data types in xquery
This example shows how we can composite up data models
which 'carry' their own operations along with them.
:)
(: using John Snelson's inspirational https://github.com/jpcs/data.xq :)
import module namespace data="http://snelson.org.uk/functions/data" at "https://raw.githubusercontent.com/jpcs/data.xq/master/data.xq";
(: one day we create a person data model :)
declare variable $person := data:declare(
<Person>
<name><data:Sequence/></name>
</Person>);
(: some time later we realise we need an address :)
declare variable $address := data:declare(
<Address>
<street><data:Sequence/></street>
<city><data:Sequence/></city>
<postcode><data:Sequence/></postcode>
</Address>);
(: example of providing custom input validation :)
declare function local:set-city(
$city
){
if($city ne "London")
then error(xs:QName('BADCITY'))
else $address[2]($city)
};
(: now for the magic, algebraic data type lets us easily compose data models :)
let $record := ($person,$address)
(: data:declare has already provided us the accessors :)
let $me := (
$record[1]("Jim Fuller"),
$record[2]("Station road"),
local:set-city("London"), (:as an example of providing custom validation:)
$record[4]("N13 9PR")
)
return
(
(: direct access values:)
$me[1](function($v){"Full Name: " || $v}), (: custom output :)
$me[2]((function($v){$v},function($v){$v},function($v){$v})),
$me[3]((function($v){$v},function($v){$v},function($v){$v})),
$me[4]((function($v){$v},function($v){$v},function($v){$v})),
(: useful data: functions for describing type and structure:)
$me ! (data:type(.),data:describe(.)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment