HannahW
HannahW

Reputation: 3

xsl substring in xpath

So what I am trying to do is from the xml get all the unique Years from the dates and then loop through the Years to get all results from that Year. The below code works up to a point but at the moment its only returning the unique full dates as I cannot work out how to get the unique values by part of the Date string (first four chracters e.g 2012). I would think to use substring within the xpath but everything I've tried seems to fail. Does anyone know what I should be doing here?

So what I want the first result to return is these values 2012,2011,2010.

This is the code I'm using below - using xslt 1.0. I'm relatively new to working with xslt so i might be missing something simple...

<!-- key at top of document -->
<xsl:key name="product" match="gdr:CompanyHistory/gdr:Event/gdr:Date" use="." />

<xsl:for-each select="gdr:CompanyHistory/gdr:Event/gdr:Date[generate-id()=generate-id(key('product',.)[1])]">
        <strong>Year = <xsl:value-of select="substring(., 1, 4)"/></strong>
        <ul>
          <xsl:variable name="Date" select="."/>
          <!-- foreach year get all results that have dates in that year.   -->
          <xsl:for-each select="gdr:CompanyHistory/gdr:Event[substring(gdr:Date, 1, 4) = $Date]">
              <li><xsl:value-of select="gdr:Description" /> - <xsl:value-of select="gdr:Date" /></li>
          </xsl:for-each>
        </ul>
      </xsl:for-each>

The xml

<CompanyHistory>
<Event>
    <Date>2012-02-16T00:00:00</Date>
    <Description>description</Description>
</Event>
<Event>
    <Date>2012-02-01T00:00:00</Date>
    <Description>description</Description>
</Event>
<Event>
    <Date>2011-03-01T00:00:00</Date>
    <Description>description</Description>
</Event>
<Event>
    <Date>2011-04-01T00:00:00</Date>
    <Description>description</Description>
</Event>
<Event>
    <Date>2010-01-26T00:00:00</Date>
    <Description>description</Description>
</Event>
<Event>
    <Date>2010-01-16T00:00:00</Date>
    <Description>description</Description>
</Event>
</CompanyHistory>

I hope this makes some sort of sense. Note: I've shortened the full xpath to make it more readable.

Upvotes: 0

Views: 1056

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167401

I would define the key solely for the year and then use Muenchian grouping. So with the stylesheet being

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

<xsl:output method="html" indent="yes"/>

<xsl:key name="year" match="CompanyHistory/Event" use="substring(Date, 1, 4)"/>

<xsl:template match="CompanyHistory">
   <xsl:apply-templates select="Event[generate-id() = generate-id(key('year', substring(Date, 1, 4))[1])]" mode="group"/>
</xsl:template>

<xsl:template match="Event" mode="group">
  <h2>Year = <xsl:value-of select="substring(Date, 1, 4)"/></h2>
  <ul>
    <xsl:apply-templates select="key('year', substring(Date, 1, 4))"/>
  </ul>
</xsl:template>

<xsl:template match="Event">
  <li>
    <xsl:value-of select="Description"/>
    <xsl:text> - </xsl:text>
    <xsl:value-of select="Date"/>
  </li>
</xsl:template>

</xsl:stylesheet>

the input

<CompanyHistory>
<Event>
    <Date>2012-02-16T00:00:00</Date>
    <Description>description</Description>
</Event>
<Event>
    <Date>2012-02-01T00:00:00</Date>
    <Description>description</Description>
</Event>
<Event>
    <Date>2011-03-01T00:00:00</Date>
    <Description>description</Description>
</Event>
<Event>
    <Date>2011-04-01T00:00:00</Date>
    <Description>description</Description>
</Event>
<Event>
    <Date>2010-01-26T00:00:00</Date>
    <Description>description</Description>
</Event>
<Event>
    <Date>2010-01-16T00:00:00</Date>
    <Description>description</Description>
</Event>
</CompanyHistory>

is transformed into

<h2>Year = 2012</h2>
<ul>
   <li>description - 2012-02-16T00:00:00</li>
   <li>description - 2012-02-01T00:00:00</li>
</ul>
<h2>Year = 2011</h2>
<ul>
   <li>description - 2011-03-01T00:00:00</li>
   <li>description - 2011-04-01T00:00:00</li>
</ul>
<h2>Year = 2010</h2>
<ul>
   <li>description - 2010-01-26T00:00:00</li>
   <li>description - 2010-01-16T00:00:00</li>
</ul>

Upvotes: 1

Related Questions