Re: Possible new key() function (Was: Re: [xsl] Finding the maximun number of nodes)

Subject: Re: Possible new key() function (Was: Re: [xsl] Finding the maximun number of nodes)
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Mon, 8 Jan 2001 15:36:59 +0000
Hi Dimitre,

>>   key('mykey', saxon:expression('. > $minValue'))
> Most convenient would be:
> key-greater(keyName, value)

Certainly more convenient and actually looking again I don't like the
suggestion I gave above because it doesn't explicitly test the key
value for the various nodes. Other related functions could be:

node-set key-less-than(string, object)
node-set key-starts-with(string, object)
node-set key-neq(string, object)
node-set key-contains(string, object)

> Whether the following will be useful:
> key-greater(keyName, nodeset-expression)
> doesn't seem immediately obvious.

Well, what it would essentially give you would be the set of nodes
with a key value greater than the minimum of the values of the nodes
in the node set passed as the second argument.  In other words, it
would stop you from having to find the minimum value in the node-set
expression before using that to access the key.  Probably of marginal
utility, but it wouldn't hurt particularly ;)

An alternative syntax would be a three-argument key:

node-set key(string, object, string?)

where the third argument specifies the relationship that should be
used to test the key values against the string values given by the
second argument.  So, for example:

  key('mykey', $minValue, '&gt;')
  key('mykey', $maxValue, '&lt;')
  key('mykey', $letters, 'starts-with')
  key('mykey', $values, '!=')
  key('mykey', $strings, 'contains')

If the third argument were omitted, it would default to '=', of

Any functions (or operators) could be given as the third argument,
even user-defined ones if specified with the appropriate namespace, as
long as they could take two string arguments. The call to the key()
function would return all nodes for which this function returns a
value that evaluates as boolean true() when passed as the first
argument a key value and as the second argument the string value of
one of the nodes in the second argument's node set.

For example, if I created a function:

boolean foo:matches(string, string)

which returns true if the first string matches the regular expression
defined in the second string, then I could do:

  key('mykey', $regexps, 'foo:matches')

to find all those nodes in 'mykey' whose key value matches one of the
regular expressions in the variable $regexps.

Another advantage of this could be that as the third argument is a
string, you could always use a variable to determine it.

And another thing. Currently, there's no way to test, for example,
whether the value of a node starts with any one of a set of values
without using an xsl:for-each.  You can't, for example, do:

  word[starts-with(., $letters)]

to find out whether the node value starts with one of the letters
defined in the $letters variable - it will only test whether it starts
with the *first* letter.

[Operators are fine because they do that implicit for-each thing on
their arguments - if 'mykey' indexes 'node' elements on their value,

  key('mykey', $values)

is exactly the same as:

  //node[. = $values]

Using a key just indicates to the processor that they should optimise
identifying nodes by that value.]

So actually something like:

  key('words', $letters, 'starts-with')

could give a work-around.

All in all, I think I'd prefer to see a third argument that limits the
search space for nodes matching the key match pattern, though, in
particular if it helped key indexing into other documents.

Just some thoughts,


Jeni Tennison

 XSL-List info and archive:

Current Thread