Reputation: 48
I am using an xsl stylesheet to extract and display selected data from an xml file on a website.
One of the data elements is a date in the format yyyy-mm-dd
. I would like to display it as, for example, Wed. May 10. Is this possible?
My overall project is to take an xml file, extract 3 data elements and put them out in a sorted order with the date display modified. I have a js
for this conversion, but without the sorting. It seemed that xsl was the answer to the sorting question but now I don't know how to (or if I can) 'intercept' the date and apply a js conversion to it and put it out in the statement: xsl:value-of select="StartTime/Date"
Upvotes: 2
Views: 4114
Reputation: 4209
You can use ddwrt:FormatDate()
<xsl:value-of select="ddwrt:FormatDate(string(@EventDate), 1033, 3)" />
The result will look like this:
Thursday, May 8, 2014
Upvotes: -1
Reputation: 52878
As LarsH mentioned, this is much easier in XSLT 2.0. Here's another 1.0 option if you don't have any dates earlier than 1901-01-07.
XML Input (Thanks Borodin!)
<document>
<date>2013-01-01</date>
<date>2013-05-24</date>
<date>2013-12-25</date>
<date>1957-07-13</date>
<date>1901-01-07</date>
</document>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="date">
<xsl:variable name="weekday" select="((xs:date(.) - xs:date('1901-01-06')) div xs:dayTimeDuration('P1D')) mod 7"/>
<xsl:variable name="month" select="substring(.,6,2)"/>
<xsl:copy>
<xsl:call-template name="getWeekday">
<xsl:with-param name="weekday" select="$weekday"/>
</xsl:call-template>
<xsl:call-template name="getMonth">
<xsl:with-param name="month" select="$month"/>
</xsl:call-template>
<xsl:value-of select="substring(.,9,2)"/>
</xsl:copy>
</xsl:template>
<xsl:template name="getWeekday">
<xsl:param name="weekday"/>
<xsl:choose>
<xsl:when test="$weekday=1">Mon. </xsl:when>
<xsl:when test="$weekday=2">Tue. </xsl:when>
<xsl:when test="$weekday=3">Wed. </xsl:when>
<xsl:when test="$weekday=4">Thu. </xsl:when>
<xsl:when test="$weekday=5">Fri. </xsl:when>
<xsl:when test="$weekday=6">Sat. </xsl:when>
<xsl:when test="$weekday=7">Sun. </xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template name="getMonth">
<xsl:param name="month"/>
<xsl:choose>
<xsl:when test="$month='01'">Jan </xsl:when>
<xsl:when test="$month='02'">Feb </xsl:when>
<xsl:when test="$month='03'">Mar </xsl:when>
<xsl:when test="$month='04'">Apr </xsl:when>
<xsl:when test="$month='05'">May </xsl:when>
<xsl:when test="$month='06'">Jun </xsl:when>
<xsl:when test="$month='07'">Jul </xsl:when>
<xsl:when test="$month='08'">Aug </xsl:when>
<xsl:when test="$month='09'">Sep </xsl:when>
<xsl:when test="$month='10'">Oct </xsl:when>
<xsl:when test="$month='11'">Nov </xsl:when>
<xsl:when test="$month='12'">Dec </xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Output
<document>
<date>Tue. Jan 01</date>
<date>Fri. May 24</date>
<date>Wed. Dec 25</date>
<date>Sat. Jul 13</date>
<date>Mon. Jan 07</date>
</document>
Upvotes: 0
Reputation: 126742
XSLT is quite capable of basic arithmetic, and the day of the week can be derived using Zeller's formula.
You would need to call the template from your own code using
<xsl:call-template name="date-format">
<xsl:with-param name="yyyy-mm-dd" select="StartTime/Date"/>
</xsl:call-template>
This stylesheet
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="date">
<xsl:copy>
<xsl:call-template name="date-format">
<xsl:with-param name="yyyy-mm-dd" select="."/>
</xsl:call-template>
</xsl:copy>
</xsl:template>
<xsl:template name="date-format">
<xsl:param name="yyyy-mm-dd"/>
<xsl:variable name="yyyy" select="substring-before($yyyy-mm-dd, '-')"/>
<xsl:variable name="mm-dd" select="substring-after($yyyy-mm-dd, '-')"/>
<xsl:variable name="mm" select="substring-before($mm-dd, '-')"/>
<xsl:variable name="dd" select="substring-after($mm-dd, '-')"/>
<xsl:variable name="Y">
<xsl:choose>
<xsl:when test="$mm < 3"><xsl:value-of select="$yyyy - 1"/></xsl:when>
<xsl:otherwise><xsl:value-of select="$yyyy + 0"/></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="y" select="$Y mod 100"/>
<xsl:variable name="c" select="floor($Y div 100)"/>
<xsl:variable name="d" select="$dd+0"/>
<xsl:variable name="m">
<xsl:choose>
<xsl:when test="$mm < 3"><xsl:value-of select="$mm + 12"/></xsl:when>
<xsl:otherwise><xsl:value-of select="$mm + 0"/></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="w" select="($d + floor(($m + 1) * 2.6) + $y + floor($y div 4) + floor($c div 4) - $c * 2 - 1) mod 7"/>
<xsl:variable name="www">
<xsl:choose>
<xsl:when test="$w = 0">Sun</xsl:when>
<xsl:when test="$w = 1">Mon</xsl:when>
<xsl:when test="$w = 2">Tue</xsl:when>
<xsl:when test="$w = 3">Wed</xsl:when>
<xsl:when test="$w = 4">Thu</xsl:when>
<xsl:when test="$w = 5">Fri</xsl:when>
<xsl:when test="$w = 6">Sat</xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:variable name="mmm">
<xsl:choose>
<xsl:when test="$mm = 1">Jan</xsl:when>
<xsl:when test="$mm = 2">Feb</xsl:when>
<xsl:when test="$mm = 3">Mar</xsl:when>
<xsl:when test="$mm = 4">Apr</xsl:when>
<xsl:when test="$mm = 5">May</xsl:when>
<xsl:when test="$mm = 6">Jun</xsl:when>
<xsl:when test="$mm = 7">Jul</xsl:when>
<xsl:when test="$mm = 8">Aug</xsl:when>
<xsl:when test="$mm = 9">Sep</xsl:when>
<xsl:when test="$mm = 10">Oct</xsl:when>
<xsl:when test="$mm = 11">Nov</xsl:when>
<xsl:when test="$mm = 12">Dec</xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="concat($www, '. ', $mmm, ' ', $d)"/>
</xsl:template>
</xsl:stylesheet>
applied to this XML data
<?xml version="1.0" encoding="UTF-8"?>
<document>
<date>2013-01-01</date>
<date>2013-05-24</date>
<date>2013-12-25</date>
<date>1957-07-13</date>
<date>1776-07-04</date>
</document>
produces this output, as required
<?xml version="1.0" encoding="utf-8"?>
<document>
<date>Tue. Jan 1</date>
<date>Fri. May 24</date>
<date>Wed. Dec 25</date>
<date>Sat. Jul 13</date>
<date>Thu. Jul 4</date>
</document>
Upvotes: 4