xsl-list
[Top] [All Lists]

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

2008-05-08 09:17:30
Hi Trish,

The issue is a context issue.  When you write:
<xsl:for-each select="//Artist[(_at_)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[(_at_)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(_at_)musictoday(_dot_)com> 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[(_at_)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[(_at_)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


 --~------------------------------------------------------------------
 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
 To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
 or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
 --~--



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--