Re: [xsl] Finding Nodes That Match Distinct Node Value

Subject: Re: [xsl] Finding Nodes That Match Distinct Node Value
From: "Darcy Parker" <darcyparker@xxxxxxxxx>
Date: Thu, 8 May 2008 12:18:55 -0400
I keep forgetting about an XSLT function called current().

<xsl:for-each select="//Artist[@festival = current()]">

will also work.

If you use current(), you don't have to create <xsl:variable
name="CurrentFestival" select="."/>

Darcy
On Thu, May 8, 2008 at 12:10 PM, Darcy Parker <darcyparker@xxxxxxxxx> wrote:
> Hi Trish,
>
>
>  The issue is a context issue.  When you write:
>  <xsl:for-each select="//Artist[@festival = .]">
>  the '.' inside the predicate refers to the Artist node being being
>  filtered with the predicate.
>  You need to save the current Festival in a variable and use this.
>
>  A simplified version of the template that does what I think you want:
>
>
>  <?xml version="1.0" encoding="utf-8"?>
>  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
>
>  <xsl:template match="/">
>
> <xsl:for-each select="//Artist/@festival[not(.=preceding::Artist/@festival)]">
>         <xsl:value-of select="concat('Festival=',.,'&#xa;')"/>
>         <xsl:variable name="CurrentFestival" select="."/>
>         <xsl:for-each select="//Artist[@festival = $CurrentFestival]">
>                 <xsl:value-of select="concat('  Artist=',@name,' Date=',Date,'
>  Stage=',Stage,'&#xa;')"/>
>
>         </xsl:for-each>
>  </xsl:for-each>
>  </xsl:template>
>  </xsl:stylesheet>
>
>  Output is:
>  Festival=2007
>   Artist=John Doe Date=08/17/07 Stage=Stage Two
>   Artist=Jane Doe Date=08/15/07 Stage=Stage Three
>   Artist=Dick Doe Date=08/16/07 Stage=Stage One
>  Festival=2006
>   Artist=Sally Doe Date=08/16/06 Stage=Stage Four
>   Artist=John Q. Public Date=08/15/06 Stage=Stage One
>  Festival=2005
>   Artist=John Smith Date=08/17/05 Stage=Stage Three
>  Festival=2004
>   Artist=Jane Smith Date=08/17/04 Stage=Stage Four
>   Artist=Sally Smith Date=08/16/04 Stage=Somethin' Else
>   Artist=Dick Smith Date=08/16/04 Stage=Stage Two
>
>
>
>  On Thu, May 8, 2008 at 11:50 AM,  <Trish@xxxxxxxxxxxxxx> wrote:
>  > Hi:
>  >
>  >  I want to loop through an xml document and get distinct values from an
>  >  attribute and then find all sibling nodes that have that attribute
>  >  value.
>  >
>  >  I'm pulling distinct festivals based on @festival within each artist
>  >  just fine, but then I want to go back and get all of the Artist info per
>  >  festival. It seems like the code I'm using to do this should work, but
>  >  it doesn't. I can't change the organization of the xml. I'm trying not
>  >  to use keys. I only have access to XSL 1.0 for this project. The line I
>  >  need help with is:
>  >  <xsl:for-each select="//Artist[@festival = .]">
>  >
>  >  I'm guessing that the value of "." is lost because I'm beginning at the
>  >  top of the document again. I'm certain that one of you has an elegant
>  >  solution.
>  >
>  >  XML fragment (url's removed on purpose):
>  >
>  >  <?xml version="1.0" encoding="utf-8" ?>
>  >  <Festival>
>  >   <Artist festival="2007" name="John Doe">
>  >     <Url>http://...</Url>
>  >     <Date>08/17/07</Date>
>  >     <Stage>Stage Two</Stage>
>  >   </Artist>
>  >   <Artist festival="2007" name="Jane Doe">
>  >     <Url>http://...</Url>
>  >     <Date>08/15/07</Date>
>  >     <Stage>Stage Three</Stage>
>  >   </Artist>
>  >   <Artist festival="2007" name="Dick Doe">
>  >     <Url>http://...</Url>
>  >     <Date>08/16/07</Date>
>  >     <Stage>Stage One</Stage>
>  >   </Artist>
>  >   <Artist festival="2006" name="Sally Doe">
>  >     <Url>http://...</Url>
>  >     <Date>08/16/06</Date>
>  >     <Stage>Stage Four</Stage>
>  >   </Artist>
>  >   <Artist festival="2006" name="John Q. Public">
>  >     <Url>http://...</Url>
>  >     <Date>08/15/06</Date>
>  >     <Stage>Stage One</Stage>
>  >   </Artist>
>  >   <Artist festival="2005" name="John Smith">
>  >     <Url>http://...</Url>
>  >     <Date>08/17/05</Date>
>  >     <Stage>Stage Three</Stage>
>  >   </Artist>
>  >   <Artist festival="2004" name="Jane Smith">
>  >     <Url>http://...</Url>
>  >     <Date>08/17/04</Date>
>  >     <Stage>Stage Four</Stage>
>  >   </Artist>
>  >   <Artist festival="2004" name="Sally Smith">
>  >     <Url>http://...</Url>
>  >     <Date>08/16/04</Date>
>  >     <Stage>Somethin' Else</Stage>
>  >   </Artist>
>  >   <Artist festival="2004" name="Dick Smith">
>  >     <Url>http://...</Url>
>  >     <Date>08/16/04</Date>
>  >     <Stage>Stage Two</Stage>
>  >   </Artist>
>  >  </Festival>
>  >
>  >  Code Excerpt:
>  >
>  >  <table align="center" border="0" cellpadding="3" cellspacing="1">
>  >    <tr align="left" valign="top">
>  >       <td>artist</td>
>  >       <td>date</td>
>  >       <td>stage</td>
>  >    </tr>
>  >    <xsl:for-each
>  >  select="//Artist/@festival[not(.=preceding::Artist/@festival)]">
>  >       <tr>
>  >          <td colspan="3">
>  >             <a name="{.}"></a>
>  >             <xsl:choose>
>  >                <xsl:when test=". = '2007'">
>  >                   2 0 0 7&#160;&#8226;&#160;<a href="#2006">2 0 0
>  >  6</a>&#160;&#8226;&#160;<a href="#2005">2 0 0 5</a>&#160;&#8226;&#160;<a
>  >  href="#2004">2 0 0 4</a><br />
>  >                </xsl:when>
>  >                <xsl:when test=". = '2006'">
>  >                   <a href="#2007">2 0 0 7</a>&#160;&#8226;&#160;2 0 0
>  >  6&#160;&#8226;&#160;<a href="#2005">2 0 0 5</a>&#160;&#8226;&#160;<a
>  >  href="#2004">2 0 0 4</a><br />
>  >                </xsl:when>
>  >                <xsl:when test=". = '2005'">
>  >                   <a href="#2007">2 0 0 7</a>&#160;&#8226;&#160;<a
>  >  href="#2006">2 0 0 6</a>&#160;&#8226;&#160;2 0 0 5&#160;&#8226;&#160;<a
>  >  href="#2004">2 0 0 4</a><br />
>  >                </xsl:when>
>  >                <xsl:when test=". = '2004'">
>  >                   <a href="#2007">2 0 0 7</a>&#160;&#8226;&#160;<a
>  >  href="#2006">2 0 0 6</a>&#160;&#8226;&#160;<a href="#2005">2 0 0
>  >  5</a>&#160;&#8226;&#160;2 0 0 4<br />
>  >                </xsl:when>
>  >                <xsl:otherwise>
>  >                   <a href="#2007">2 0 0 7</a>&#160;&#8226;&#160;<a
>  >  href="#2006">2 0 0 6</a>&#160;&#8226;&#160;<a href="#2005">2 0 0
>  >  5</a>&#160;&#8226;&#160;<a href="#2004">2 0 0 4</a><br />
>  >                </xsl:otherwise>
>  >             </xsl:choose>
>  >          </td>
>  >       </tr>
>  >       <xsl:for-each select="//Artist[@festival = .]">
>  >          <tr>
>  >             <td><a href="{Url}"><xsl:value-of select="@name" /></a></td>
>  >             <td><xsl:value-of select="Date" /></td>
>  >             <td><xsl:value-of select="Stage" /></td>
>  >          </tr>
>  >       </xsl:for-each>
>  >    </xsl:for-each>
>  >  </table>
>  >
>  >  Thank you so much in advance,
>  >  Trish

Current Thread