Thanks for the pat on the back. I left a useless <if> in one stylesheet. I've eliminated that, eliminated the <datenum> from the sort output, and cleaned up the comments. Changed stylesheets included. I think this will be the last of the changes :-)The Showcase is available in its entirety as a ZIP archive. Included in this archive are XSLT stylesheets to reformat The Register. This is a particularly good example of XSL transformation.
Ed
<?xml version="1.0" encoding="UTF-8"?>
<?jpluck name="The Register"
description="Extract the article headings"
hidden="yes"
?>
<!-- written by Edward Rayl -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"
indent="yes"
omit-xml-declaration="no"
encoding="utf-8"/>
<xsl:template match="/">
<html>
<head>
<!-- Get the title -->
<base href="http://theregister.com/"/>
<xsl:copy-of select="/html/head/title"/>
</head>
<body link="#0000DD" bgcolor="white">
<!-- Get the current update date -->
<xsl:variable name="updated">
<xsl:value-of select="//[EMAIL PROTECTED]'indexdate']"/>
</xsl:variable>
<!-- Insert the 'Updated' string in the output stream
Use a <div> to make it appear similar to article <div>'s -->
<div>
<!-- Get the current banner image and format the update date-->
<xsl:copy-of select="/html/body/table[1]//tr[1]/td[2]/a/*"/>
<br/>
<xsl:value-of select="normalize-space(substring-before($updated,'Updated:'))"/>
<br/>Updated:
<xsl:value-of select="normalize-space(substring-after($updated,'Updated:'))"/>
<!-- Use a large datenum to make this div sort to the top
Remember we will use a descending sort -->
<date datenum="999999999999"/>
</div>
<!-- Get the article titles. We will sort the articles in the chained stylesheet -->
<xsl:apply-templates select="//table[position()=2]//tr[position()=1]/td[position()=2]/table[position()=1]//tr[position()=2]/td/*"/>
</body>
</html>
</xsl:template>
<!-- Dates are in the form of '2 March 2003 8:32am', which makes it
impossible to sort
Modify this date to the normalized form of 'yyyymmddhhmm', using 24 hour format
Add this 'date number' to the <div> as a <date datenum="yyyymmddhhmm">
element to used by the chained stylesheet -->
<xsl:template match="div[(@class = 'indexposted')]">
<xsl:variable name="datenum">
<xsl:call-template name="parseDate">
<xsl:with-param name="date"/>
</xsl:call-template>
</xsl:variable>
<xsl:element name="date">
<xsl:attribute name="datenum"><xsl:value-of select="$datenum"/></xsl:attribute>
</xsl:element>
<xsl:value-of select="."/>
<br/>
</xsl:template>
<!-- Process all <div>'s -->
<xsl:template match="div">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<!-- Process miscellaneous tags in the input document -->
<xsl:template match="node() | @*">
<xsl:copy-of select="."/>
</xsl:template>
<!-- Date conversion routine -->
<xsl:template name="parseDate">
<xsl:variable name="date" select="."/>
<xsl:variable name="day" select="substring-before($date, ' ')"/>
<xsl:variable name="daylength" select="string-length($day)"/>
<xsl:variable name="daynum">
<!-- Change a single digit day to double digit with leading zero -->
<xsl:choose>
<xsl:when test="$daylength = '1'">
<xsl:value-of select="concat('0',$day)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$day"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="month" select="substring-before(substring($date, $daylength + 2), ' ')"/>
<xsl:variable name="monthlength" select="string-length($month)"/>
<xsl:variable name="monthnum">
<!-- Change a month name to two digit month number -->
<xsl:call-template name="getMonthNum">
<xsl:with-param name="monthname" select="$month"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="year" select="substring-before(substring($date, $daylength + $monthlength + 3), ' ')"/>
<xsl:variable name="time" select="substring($date, $daylength + $monthlength + 8)"/>
<xsl:variable name="timelength" select="string-length($time)"/>
<xsl:variable name="timenum">
<!-- Normalize 12 hour time with am/pm to 24 hour time without a ':' -->
<xsl:choose>
<xsl:when test="substring(substring-after($time, ':'), 3, 1) = 'p'">
<!-- Process pm times -->
<xsl:choose>
<!-- 12:xxpm times do NOT get 12 added to them -->
<xsl:when test="string(number(substring-before($time, ':'))) = 12">
<xsl:value-of select="concat(string(number(substring-before($time, ':'))), substring(substring-after($time, ':'), 1, 2))"/>
</xsl:when>
<!-- add 12 to the time -->
<xsl:otherwise>
<xsl:value-of select="concat(string(number(substring-before($time, ':')) + 12), substring(substring-after($time, ':'), 1, 2))"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<!-- Process am times -->
<xsl:choose>
<xsl:when test="string-length($time) = '6'">
<!-- Add a leading zero to single digit hours -->
<xsl:value-of select="concat('0',substring($time, 1, 1), substring(substring-after($time, ':'), 1, 2))"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat(substring($time, 1, 2), substring(substring-after($time, ':'), 1, 2))"/>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="concat($year, $monthnum, $daynum, $timenum)"/>
</xsl:template>
<!-- Change a month name to two digit month number -->
<xsl:template name="getMonthNum">
<xsl:param name="monthname" select="."/>
<xsl:choose>
<xsl:when test="$monthname = 'January'">01</xsl:when>
<xsl:when test="$monthname = 'February'">02</xsl:when>
<xsl:when test="$monthname = 'March'">03</xsl:when>
<xsl:when test="$monthname = 'April'">04</xsl:when>
<xsl:when test="$monthname = 'May'">05</xsl:when>
<xsl:when test="$monthname = 'June'">06</xsl:when>
<xsl:when test="$monthname = 'July'">07</xsl:when>
<xsl:when test="$monthname = 'August'">08</xsl:when>
<xsl:when test="$monthname = 'September'">09</xsl:when>
<xsl:when test="$monthname = 'October'">10</xsl:when>
<xsl:when test="$monthname = 'November'">11</xsl:when>
<xsl:when test="$monthname = 'December'">12</xsl:when>
<xsl:otherwise>error: <xsl:value-of select="$monthname"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<?jpluck name="The Register"
description="Sort the article headings from The Register
- chained from register-indx.xsl"
hidden="yes"
?>
<!-- written by Edward Rayl -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"
indent="yes"
omit-xml-declaration="no"
encoding="utf-8"/>
<!-- The URI of the XML/HTML page being transformed. -->
<xsl:template match="/">
<!-- Build the html document shell to hold the sorted <div>'s -->
<html>
<head>
<xsl:copy-of select="/html/head/node()"/>
</head>
<body>
<xsl:apply-templates select="/html/body"/>
</body>
</html>
</xsl:template>
<!-- Once in the body, sort the <div>'s based on the <date> tag -->
<xsl:template match="body">
<xsl:for-each select="div">
<!-- Reverse sort to display the latest news at the top of the page -->
<xsl:sort order="descending" select="date/@datenum"/>
<!-- Grab everything except the <datenum>, we don't need it anymore -->
<xsl:copy-of select="*[name() != 'datenum'] | text()"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

