Re: [xsl] How to use xsl:key to get all values?

Subject: Re: [xsl] How to use xsl:key to get all values?
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Fri, 13 Apr 2001 10:34:28 +0100
Hi Di,

I think that you're trying to focus the key to get back only those
nodes returned by the key that are also descendants of the current
node.  In other words, you are iterating over the CC elements, and
want to find those EE elements that are descendants of that CC element
and that have 'a1' as the value of their 'aField' attribute.

As Mike has pointed out, you can find only those under a particular
element by including an identifier for that element in the key value,
so you could do:

<xsl:key name="key-name" match="EE"
         use="concat(generate-id(ancestor::CC), ':', @aField)" />
<xsl:template match="AA/BB">
   <xsl:for-each select="CC">
      <xsl:variable name="child"
                    select="key('key-name', concat(generate-id(), ':a1')" />
      <xsl:value-of select="$child/@value" />

Another option is to retrieve all the EE elements with that particular
aField using the key, and then filter them to find only those who have
the current CC element as an ancestor:

<xsl:key name="key-name" match="EE" use="@aField)" />
<xsl:template match="AA/BB">
   <xsl:for-each select="CC">
      <xsl:variable name="child"
                    select="key('key-name', 'a1')
                               [count(ancestor::CC | current()) = 1]" />
      <xsl:value-of select="$child/@value" />

[Note: The predicate on the key there is a way of testing whether two
nodes are the same using set logic, sometimes known as the "Kaysian
Intersection" method. You could equally use:

  generate-id(ancestor::CC) = generate-id(current())

if you prefer.]

Which of these two options gives better performance depends on the
structure of your source. If you're worried about performance, then
you should try both, time them and see what difference it makes.

I hope that helps,


Jeni Tennison

 XSL-List info and archive:

Current Thread