Re: [xsl] problem using self::node() in for-each

Subject: Re: [xsl] problem using self::node() in for-each
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Fri, 21 May 2004 17:48:50 +0100
Hi Garrett,

> The inf_source_id in the <information type="info"> refers to the
> inf_source_id in the <information type="source">
> i.e. Information 1 has inf_source_id of 2 meaning it came from Source 2.
>
> I'm trying to output all the inf_text using xsl:for-each along with the name
> of the source it has a reference to through inf_source_id.

I think that the problem is with the setting of the $inf_source
variable here:

>         <xsl:variable name="inf_source"
> select="/root/information/instance[inf_type = 'source' and (inf_source_id =
> ./inf_source_id)]/inf_name"/>

In the predicate, you test whether:

  inf_source_id = ./inf_source_id

This is always true (the <inf_source_id> of the context node is always
equal to itself), so the $inf_source is set to the <inf_name> children
of all the <instance> elements whose <inf_type> is 'source'.

You should be using the current() function to get the <inf_source_id>
of the current node within the <xsl:for-each>, which is a <instance>
element whose <inf_type> is 'info'. Try the path:

  /root
    /information
      /instance[inf_type = 'source' and
                inf_source_id = current()/inf_source_id]
        /inf_name

You might also consider using a key to retrieve the relevant
<instance> element. Index all the <instance> elements whose <inf_type>
is 'source' by their <inf_source_id>:

<xsl:key name="sources"
         match="instance[inf_type = 'source']"
         use="inf_source_id" />

and then retrieve them with the key() function:

  <xsl:variable name="inf_source"
                select="key('sources', inf_source_id)" />

This is easier to write, and will be more efficient if you have large
files to deal with.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/

Current Thread