Declarative sorting

DECLARATIVE SORTING

REQUIREMENTS

The aim is to specify declaratively that a nodeset is sorted.

* At initialisation, the system ensures that the data is sorted.
* During recalculation, a change to a field that is part of a sorting dependency may cause the (parent) item to be moved.
* An <insert/> action ensures that the new item is inserted at the correct position (and ignoring any other positioning details attached to the insert action).

Sorting should principally be expressed using binds.

It should be possible to allow controls that deal with nodesets (repeat and select/1) to separately specify a presentation sorting.

Simple cases should be easy, complex cases should be possible: many sort requirements are very simple (for instance on a name or a date, etc), with only an additional up/down sorting order parameter; however there are other more complex cases, such as multiple sort fields, and collation orders.

SIMPLE BINDING

There are three new bind properties: 
 @sort: XPath expression, default is empty, which means that no sorting is done; items remain in document order.
 @direction: "up"|"down", determines whether to sort increasing or decreasing; default is up
 @collation: URI, See https://www.w3.org/2013/collation/UCA/

If a bind has such a property, such as:

 <bind ref="item" sort="date"/>

then the nodeset referenced is kept sorted by the system, using the XPath 
expression as key.

Other examples:

 <bind ref="item" sort="lowercase(name)"/>
 <bind ref="instance('data')" sort="substring(date, 6, 2)" />
 <bind ref="instance('books')" sort="."/>

COMPLEX BINDING

In this case you want to specify a set of sorting fields.

Strawman:

 <bind ref="book" sort="title">
  <bind sort="author"/>
  <bind sort="year"/>
  <bind sort="publisher"/>
 </bind>

which states that the books should principally be ordered by title, but with equal titles then sorted by author, then the year, and then the publisher.

USE ON CONTROLS

Just as with other bind properties, they are also applicable on controls: 

 <repeat ref="item" sort="received-date">
     ...
     
For the complex case, you could use a bind:

 <bind id="purchases" ref="item" sort="received-date">
  <bind sort="ordered=-date">
 </bind>
 ...
 <repeat bind="purchases">
    ...

FUNCTIONS IN RELATED LANGUAGES

Just as a reference, here are sorting functions in other languages.

https://doc.orbeon.com/xforms/xpath/standard-functions#exforms-functions

exf:sort(
    $sequence   as item()*,
    $sort-key   as xs:string,
    $datatype   as xs:string?,
    $order      as xs:string?,
    $case-order as xs:string?
) as item()*

https://web.archive.org/web/20120706065000/http://exforms.org/sorting.html
https://docs.seneca.nl/Formulierenserver-Docs/XForms/XForms-Extensions/Extension-functions/The-sort()-function.html

   node-set exf:sort(node-set data, string xpath-expr, string? data-type, string? ascending-descending, string? lowerfirst-or-upperfirst)

   node-set sxf:sort(node-set expression, sort expression, language, data-type, order, case-order) 

   node-set expression: Required XPath expression used to select the nodes which must be sorted.
   sort expression: Required XPath expression used for selecting the keys on which to sort.
   language (optional): Specifies the locale used for sorting the keys. Defaults to an empty string, in which case the system environments default locale is used.
   data-type (optional): Specifies the type of data for sorting purposes: text or number (text is the default).
   order (optional): Specifies the sorting order: ascending or descending (ascending is the default).
   case-order: Specifies how to sort uppercase and lowercase letters: none, upperfirst or lowerfirst (upperfirst is the default).

https://doc.orbeon.com/xforms/xpath/extension-functions/extension-xml#xxf-sort

xxf:sort(
    $sequence   as item()*,
    $sort-key   as item(),
    $datatype   as xs:string?,
    $order      as xs:string?,
    $case-order as xs:string?
) as item()*

   … the sort keys used to be a string, and we made it a path... but that may not be correct from xpath semantics
   … the key should really be a function but we can't support that

https://www.w3.org/TR/xpath-functions-31/#func-sort

   fn:sort($input as item()*) as item()*
   fn:sort($input as item()*, $collation as xs:string?) as item()*
   fn:sort($input as item()*, $collation as xs:string?, $key as function(item()) as xs:anyAtomicType*) as item()*

Steven

Received on Thursday, 20 November 2025 12:56:09 UTC