Subject: Re: 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=',.,'
')"/>
> <xsl:variable name="CurrentFestival" select="."/>
> <xsl:for-each select="//Artist[@festival = $CurrentFestival]">
> <xsl:value-of select="concat(' Artist=',@name,' Date=',Date,'
> Stage=',Stage,'
')"/>
>
> </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 • <a href="#2006">2 0 0
> > 6</a> • <a href="#2005">2 0 0 5</a> • <a
> > href="#2004">2 0 0 4</a><br />
> > </xsl:when>
> > <xsl:when test=". = '2006'">
> > <a href="#2007">2 0 0 7</a> • 2 0 0
> > 6 • <a href="#2005">2 0 0 5</a> • <a
> > href="#2004">2 0 0 4</a><br />
> > </xsl:when>
> > <xsl:when test=". = '2005'">
> > <a href="#2007">2 0 0 7</a> • <a
> > href="#2006">2 0 0 6</a> • 2 0 0 5 • <a
> > href="#2004">2 0 0 4</a><br />
> > </xsl:when>
> > <xsl:when test=". = '2004'">
> > <a href="#2007">2 0 0 7</a> • <a
> > href="#2006">2 0 0 6</a> • <a href="#2005">2 0 0
> > 5</a> • 2 0 0 4<br />
> > </xsl:when>
> > <xsl:otherwise>
> > <a href="#2007">2 0 0 7</a> • <a
> > href="#2006">2 0 0 6</a> • <a href="#2005">2 0 0
> > 5</a> • <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
|