index(sequence, expression)
index(sequence, expression, collation)
The first argument is any sequence. Usually it will be a sequence of nodes, but this is not essential. This is the sequence being indexed.
The second argument evaluates to an XPath expression. Most commonly, the argument will be written as a call to the saxon:expression() extension function. This expression is evaluated once for each item in the sequence being indexed, with that item as the context node. (The context position and size reflect the position of this item in the sequence, but this will not normally be useful.) The result of the expression is atomized. Each value in the atomized result represents a key value: the item in the indexed sequence can be efficiently found using any of these key values.
If a key value is of type xdt:untypedAtomic
, it is treated as a string. If you want to treat
the value as numeric, say, then perform a conversion within the expression.
The optional third argument is the URI of a collation to be used when comparing strings. For example, if you
want string matching to be accent- and case-blind, specify "http://saxon.sf.net/collation?strength=primary"
.
For example, consider a source document of the form:
<doc>
<town name="Amherst" state="NH"/>
<town name="Amherst" state="MA"/>
<town name="Auburn" state="MA"/>
<town name="Auburn" state="NH"/>
<town name="Auburn" state="ME"/>
<town name="Bristol" state="RI"/>
<town name="Bristol" state="ME"/>
<town name="Bristol" state="CT"/>
<town name="Bristol" state="NH"/>
<town name="Bristol" state="VT"/>
<town name="Cambridge" state="ME"/>
</doc>
and suppose there is a requirement to find town
elements efficiently given the abbreviation for the
state
. You can do this by first setting up an indexed sequence. In XQuery you can write:
declare namespace saxon="http://saxon.sf.net/";
declare variable $indexedTowns := saxon:index(//town, saxon:expression("@state"));
This could be a local variable (declared in a let
clause) rather than a global variable.
The XSLT equivalent is:
<xsl:variable name="indexedTowns"
select="saxon:index(//town, saxon:expression('@state'))"/>
You can then find all the towns in New Hampshire using the expression:
saxon:find($indexedTowns, "NH")
Indexed sequences are primarily useful in XQuery, where they provide functionality equivalent to the
standard xsl:key
mechanism in XSLT. There are some cases, however, where indexed sequences
can also be useful in XSLT. One example is where there is a need for an index to span multiple documents: the
XSLT key()
function will only search within a single document.
As well as using an indexed sequence in the first argument to the saxon:find()
function,
you can use it in any other place where a sequence is expected, in which case the value is the sequence
that was passed as the first argument to saxon:index()
.
The saxon:index
function is available only with Saxon-SA.
For examples of use, see saxon:index().