Re: [xsl] Group by Element based on Attribute inside container using 1.0

Subject: Re: [xsl] Group by Element based on Attribute inside container using 1.0
From: Michael Ludwig <mlu@xxxxxxxxxxxxx>
Date: Wed, 12 Nov 2008 16:53:14 +0100
Friend, Darris E schrieb:
Outstanding! I did a little research on the Sort. Your method did sort
by year, but not exactly the way I wanted. Partly because I did not
mention the most recent year first.

And partly, and probably more significantly, because one of my substring expressions was wrong. I wrote substring( $date, 6, 4) to select the year part of the string "DD/MM/YYYY", but that selects "/YYY" whereas it should be "YYYY", which requires substring( $date, 7, 4). As I wrote, substring() in XPath is 1-based, not 0-based.

So the last digit of the year wasn't taken into account, which provided
a wrong result.

I altered your statement removing the concat and two substrings (also
note the third argument for substring is dropped) and produced the
following:

<xsl:sort select="substring( ObjectClassField[ @name = 'Date
Inspected'], 6)" order="descending"/>

This sorts on "/YYYY", and it accidentally works here, as in your data sample there don't seem to be two inspections in one year. It would be more robust, however, to use either YYYYMMDD:

<xsl:sort select="concat(
  substring( ObjectClassField[ @name = $inspected], 7, 4),
  substring( ObjectClassField[ @name = $inspected], 1, 2),
  substring( ObjectClassField[ @name = $inspected], 4, 2))"/>

Or YYYY, then MM, then DD:

<xsl:sort select="substring(ObjectClassField[@name = $inspected], 7, 4)"/>
<xsl:sort select="substring(ObjectClassField[@name = $inspected], 1, 2)"/>
<xsl:sort select="substring(ObjectClassField[@name = $inspected], 4, 2)"/>

With a variable $inspected defined outside the xsl:apply-templates or
xsl:for-each that is sorted:

<xsl:variable name="inspected" select="'Date Inspected'"/>

And of course sorting years as strings only works when they all have the
same number of digits, so in order to sort years like -44 (44 BC), 0,
800, or 10123, you want:

<xsl:sort select="Year" data-type="number"/>

But then, you'd also need some more intelligent substring work to parse
the dates.

Thank you for your help and patience.
darris

You're very welcome, thanks for reporting back.


Michael Ludwig

Current Thread