Sort a set of nodes within or across documents in ascending or descending order. The sort criterion is specified by a relative location path.
In Tamino, you can use a SortByClause
for sort operations
using the following keywords:
If there is a collation defined for the element or attribute that is
used as sort criterion, then the sort will be based on that collation. You can specify multiple
sort criteria by separating them with a comma. The default sorting order is
ascending, but you can also specify a descending order (see
SortByCharacteristics
).
It is an error, if the sort argument expression evaluates to more than one node. For example, given the XML document
<A> <B>Item1</B> <B>Item2</B> </A>
the error INOXIE8309 will occur when trying A sortby (B)
or A sortall (B)
, since it is not clear which B
node
to take as the sort criterion. In cases like these, the following table helps
you finding a unique sort expression
(sort
standing for sortby
and for sortall
):
A sort
(B[1]) |
first element |
A sort
(B[last()]) |
last element |
A sort (B[. =
max(../B)]) |
maximum numerical value |
A sort (B[. =
min(../B)]) |
minimum numerical value |
A sort
(B[not(. < ../B)]) |
maximum string value |
A sort
(B[not(. > ../B)]) |
minimum string value |
To guarantee a type-conforming sort, you should use a structure index for the doctype in question that uses at least the setting "CONDENSED" .
It is an error to address the parent nodes after applying a sort operation. For example:
/patient/name sortall (.) /..
will yield error INOXIE8345.
You can use only one sortall
operation at a time. For
example,
(/patient/name sortall (.)) sortall (.)
will yield error INOXIE8355.
The following restriction applies to sortby
operations
within a document:
You cannot sort by the results of a function call such as /*/*
sortby(position() desc)
.
There is no SortByClause
in XPath.
In previous versions, a sortby
expression that is
immediately located after the root node (e.g. /A sortby (.)
, has
the same semantics as /A sortall (.)
now, namely performing an
inter-document sorting. This has been retained for compatibility.
Select all firstname
descendant nodes and return them
sorted within each document:
//firstname sortby (.)
This yields the following list of result nodes:
<firstname ino:id="1">Dorothy</firstname> <firstname ino:id="1">John</firstname> <firstname ino:id="1">John</firstname> <firstname ino:id="1">Paul</firstname> <firstname ino:id="2">A.</firstname> <firstname ino:id="2">Fred</firstname>
Select all firstname nodes in ascending order across documents
//firstname sortall (.)
An error INOXIE8355 will occur, because the example data uses
firstname
nodes at several positions in the document tree. You can
work around this by using a union set of all six possible nodes explicitly:
(/patient/name/firstname | /patient/nextofkin/name/firstname | /patient/submitted/doctor/name/firstname | /patient/result/deceased/doctor/name/firstname | /patient/result/discharged/doctor/name/firstname | /patient/result/transferred/doctor/name/firstname) sortall (.)
This yields the correct list, namely all occurrences of
firstname
nodes sorted across all document instances:
<firstname ino:id="2">A.</firstname> <firstname ino:id="1">Dorothy</firstname> <firstname ino:id="2">Fred</firstname> <firstname ino:id="1">John</firstname> <firstname ino:id="1">John</firstname> <firstname ino:id="1">Paul</firstname>
Get an alphabetically sorted list of all brands of medicine which has been used in the form of tablets and in liquid form.
(//type[@form='tablet'] | //type[@form='liquid']) sortall (@brand)
Select all male patients sorted by their surnames using an
inter-document sort; sort the node-set resulting from /patient[sex ~=
'male']
by the element /patient/name
and return the list in
descending order:
/patient[sex ~= 'male'] sortall (name desc)
Step |
SetExpr,
FilterExpr |