Record types
Record types do not introduce a new kind of XDM value; rather, they provide a new way of
constraining the content of a map. For example, the record type record(longitude
as xs:double, latitude as xs:double) matches a map if it has exactly two
entries, with the keys "longitude" and "latitude" (as instances of
xs:string), and associated values of type xs:double.
A record type can be used wherever an item type is recognised, for example in the type
signature of a function or variable, or in an instance of expression.
For example:
record(ssn as xs:string, emp as element(employee))or:
record('first name', 'middle initial', 'last name')The instances of a record type are maps. A record type is essentially a way of defining
a more precise type for maps. The first example will be satisfied by any map with two
entries: an entry whose key is "ssn" and whose value is a string, and an entry whose key
is "emp" and whose value is an employee element. The second example matches
any map with entries having the keys "first name" and "middle initial" and "last name",
regardless of the types of the values.
So for every field defined in the record definition, the map will typically contain an entry whose key matches the field name and whose value matches the corresponding type. The entry is allowed to be absent only if the type definition indicates that an empty sequence would be acceptable.
Record types are useful where maps are used to hold information with a regular structure; for example when a function accepts maps as input or returns maps as output. Declaring the argument or result type of a function as a record type often gives better information about the expected contents than when it is declared as a map.
Record types can be used as XSLT patterns, to match maps (regardless whether the value was
originally declared as a record or not). This can be especially useful when processing
JSON. For example, if a JSON document containing the object {'long': 23.1234,
'lat':55.624} is parsed using the parse-json() or
json-doc() functions, then the resulting map can be processed using a
template rule declared with match="~record(lat, long)".
The following XSLT example shows a couple of functions from a library designed to
perform complex number arithmetic, where a complex number is defined as the type
record(r as xs:double, i as xs:double):
The same functions could be written in XQuery:
declare function cx:complex ($real as xs:double, $imag as xs:double) as record(r as xs:double, i as xs:double) { map{'r':$real, 'i':$imag} }; declare function cx:add ($x as record(r as xs:double, i as xs:double), $y as record(r as xs:double, i as xs:double)) as record(r as xs:double, i as xs:double) { cx:number($x?r + $y?r, $x?i + $y?i) };Built-in record types
In XPath 4.0, there are a number of built-in named record types, including:
fn:load-xquery-module-record- holds the result of fn:load-xquery-modulefn:parsed-csv-structure-record- holds the result of fn:parse-csvfn:random-number-generator-record- holds the result of fn:random-number-generatorfn:schema-type-record- represents the properties of a simple or complex type in a schemafn:uri-structure-record- represents the components of a URI (used by the new fn:build-uri and fn:parse-uri functions)fn:dateTime-record- represents the seven components of anxs:dateTimevalue (used by the new fn:build-dateTime and fn:parts-of-dateTime functions)
These types are used to define the argument and/or result types of functions in the standard function library. In principle they can also be used directly as type names, or as constructor functions to create instance records, but this is not well developed in the specifications, in the test suite, or in the Saxon 13 implementation.