Re: [xsl] xsl:key confusion

Subject: Re: [xsl] xsl:key confusion
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Thu, 2 May 2002 10:18:26 +0100
Hi Ian,

> How do I reference a nodelist that is made up of nodes with no text
> or attributes?

Do you mean, what expression should you put in the use attribute if a
node doesn't have some text or an attribute? It depends -- why are you
creating the key? How do you *need* to get at the nodes? Do you need
to get all the nodes with the same name at the same time? Or do you
want to quickly get at a node based on its generated ID?

> How do I check to see if there are any nodes in a key?

As long as there are nodes that match the match pattern of your key
then there will be nodes in your key. So what you're actually asking
is how you find out whether there are any nodes in your document that
match the pattern of your key. You can find that out by trying to
select that kind of node from the document, which is usually as simple


For example with your key definition:

<xsl:key name="pumptestlist" match="pumptest" use="position()"/>

you could use:

  <xsl:if test="//pumptest">
    There are pumptest elements indexed by the key.

If you mean how do you find out whether there are nodes in the key
with a particular value, just try to get hold of them with the key
function, and if you get any then it's worked. For example:

  <xsl:if test="key('pumptestlist', 1)">
    There are nodes in the key with the value 1.

> I have got the following lines to work, but don't know if they are
> the correct way to do what I want
> <xsl:key name="pumptestlist" match="pumptest" use="position()"/>
> <xsl:choose>
>                 <xsl:when test="count(key('pumptestlist', '1'))>0">

You haven't described what you want, so I can't tell whether this is
what you want, but I doubt that it is. What you've done here is index
all the pumptest elements by their position. position() is a very
weird thing to use in the use attribute of xsl:key because it will
always evaluate to 1. So what you've effectively done is indexed all
the pumptest elements in the document with the value 1.

Then you're testing whether the number of nodes retrieved through the
value '1' from the key 'pumptestlist' is greater than 0. This is
exactly the same as doing:

  <xsl:when test="key('pumptestlist', '1')">

because the test attribute always evaluates the expression it contains
as a boolean value, and node sets are boolean true if they contain
nodes, and false if they don't.

Since all the pumptest elements have the same value in the key, this
is exactly the same as doing:

  <xsl:when test="//pumptest">

If you want to have a central store of all the pumptest elements, then
it's better to use a global variable than to use a key. Just declare a
global variable like this:

<xsl:variable name="pumptestlist" select="//pumptest" />

and then refer to that variable to test whether there are any pumptest
elements and to do things with them:

  <xsl:when test="$pumptest">

If the pumptest elements are in a particular location within the
document, it would be a lot better to make a more specific path to
narrow that down, for example:

<xsl:variable name="pumptestlist" select="/tests/pumptests/pumptest" />

if all the pumptest elements were children of pumptests elements that
were children of the tests document element.



Jeni Tennison

 XSL-List info and archive:

Current Thread