I am trying to format an XML date using XSLT/X-Path.
I have: PostDate="2014-03-27"
I'd like to to render as: March 27, 2014
.
I have read that XSLT may not be the way to go. Is JavaScript a better way? Can someone please offer some assistance?
Thank you!
Robin
Here are some XSLT and XPath solutions. If you are going to process this at the client-side (browser) you will have to stick to the XSLT 1.0 solution (or use JavaScript). If you generate your result somewhere else (standalone or server-side), you might be able to use a XSLT2/XPath3 compatible processor.
XPath 3.0 solution
format-date(//*/@PostDate, '[MNn] [D01], [Y0001]')
XSLT solutions
Source XML:
<Message PostDate="2014-03-27">Some text</Message>
XSLT 2.0 stylesheet:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html"/>
<xsl:template match="Message">
<date>
<xsl:value-of select="format-date(@PostDate, '[MNn] [D01], [Y0001]')"></xsl:value-of>
</date>
</xsl:template>
</xsl:stylesheet>
XSLT 1.0 stylesheet
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html"/>
<xsl:template name="month-name">
<xsl:param name="month"/>
<xsl:if test="$month = 1">January</xsl:if>
<xsl:if test="$month = 2">February</xsl:if>
<xsl:if test="$month = 3">March</xsl:if>
<xsl:if test="$month = 4">April</xsl:if>
<xsl:if test="$month = 5">May</xsl:if>
<xsl:if test="$month = 6">June</xsl:if>
<xsl:if test="$month = 7">July</xsl:if>
<xsl:if test="$month = 8">August</xsl:if>
<xsl:if test="$month = 9">September</xsl:if>
<xsl:if test="$month = 10">October</xsl:if>
<xsl:if test="$month = 11">November</xsl:if>
<xsl:if test="$month = 12">December</xsl:if>
</xsl:template>
<xsl:template name="format-iso-date">
<xsl:param name="iso-date"/>
<xsl:variable name="year" select="substring($iso-date, 1, 4)"/>
<xsl:variable name="month" select="substring($iso-date, 6, 2)"/>
<xsl:variable name="day" select="substring($iso-date, 9, 2)"/>
<xsl:variable name="month-name">
<xsl:call-template name="month-name">
<xsl:with-param name="month" select="$month"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="concat($month-name, ' ',$day, ', ', $year)"/>
</xsl:template>
<xsl:template match="Message">
<date>
<xsl:call-template name="format-iso-date">
<xsl:with-param name="iso-date" select="@PostDate"/>
</xsl:call-template>
</date>
</xsl:template>
</xsl:stylesheet>
XSLT output:
<date>March 27, 2014</date>
You can also use the date
functions in the EXSLT extension: http://www.exslt.org/
Here is yet another method to format dates like this if you are stuck using the MSXML XSL 1.0 processor by Microsoft. You'll need to use Javascript/JScript (or another language such as C#).
When adding in code this way, don't forget to use CDATA sections to make sure the XSL processor skips over certain symbols in the code sections.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="http://mycompany.com/mynamespace">
<msxsl:script language="jscript" implements-prefix="user"><![CDATA[
function jsdate()
{
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth()+1; //January is 0!
var yyyy = today.getFullYear();
if(dd<10){
dd='0'+dd
}
if(mm<10){
mm='0'+mm
}
var today = dd+'/'+mm+'/'+yyyy;
return today;
}
//]]></msxsl:script>
<xsl:template match= "/">
<xsl:apply-templates select="MySection"/>
</xsl:template>
<xsl:template match="MySection">
<IssueDate><xsl:value-of select="user:jsdate()"/></IssueDate>
</xsl:template>
</xsl:stylesheet>