Been trying to format the text to display as DD-MM-YYYY when pulled from XML to XSLT 1.0, since I know it has to be laid out as YYYY-MM-DD within XSD/XML when using xs:date whic
I would use different solutions from those provided by @Stormtroopr for both 1.0 and 2.0.
In 2.0 use
format-date(xs:date($date), '[D01]-[M01]-[Y0001]')
In 1.0 use
concat(substring(., 9, 2),
'-',
substring(., 6, 2),
'-',
substring(., 1, 4))
For future reference, please tell us which version of XSLT you are using. Both 1.0 and 2.0 are in common use, and the solutions are often different.
I am using it for SharePoint and I solved it like this
<xsl:value-of select=" ddwrt:FormatDate(/dsQueryResponse/Rows/Row/@Date,3,1)"/>
Another simple solution for producing dates in dd/mm/yyyy form
<xsl:value-of select="
concat(substring(@date, 9, 2),
'/',
substring(@date, 6, 2),
'/',
substring(@date, 1, 4))"/>
In XSLT 2.0 you can use tokenize to split the string and then just using xsl:for-each
and xsl:sort
to reverse it. (I don't have an XSLT2.0 engine right now, but this is pretty close to what you'll need).
<xsl:for-each select="tokenize(@date,'-'">
<xsl:sort select="position()" data-type="number" order="descending"/>
<xsl:value-of select="."/>
</xsl:for-each>
In XSLT 1.0, you do it using... recursion!
Here is the crux of it, this takes a date, and then searches for the string before and after the first hyphen (-
). Normally, you'd have the substring-before
come after the processing of the subtring-after
to preserve the order, but here we switch them to ultimately reverse the ouput.
<xsl:template name="reverse-date">
<xsl:param name="text" select="."/>
<xsl:choose>
<xsl:when test="contains($text, '-')">
<xsl:call-template name="reverse-date">
<xsl:with-param name="text" select="substring-after($text, '-')"/>
</xsl:call-template>
<xsl:text>-</xsl:text>
<xsl:value-of select="substring-before($text, '-')" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Below is the complete template that will reverse the date for you based on your above XML document.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates select="//event"/>
</xsl:template>
<xsl:template match="event">
<xsl:element name="date">
<!--
** Call this template when you want to reverse the date **
-->
<xsl:call-template name="reverse-date">
<xsl:with-param name="text" select="@date" />
</xsl:call-template>
</xsl:element>
</xsl:template>
<xsl:template name="reverse-date">
<xsl:param name="text" select="."/>
<xsl:choose>
<xsl:when test="contains($text, '-')">
<xsl:value-of select="substring-before($text, '-')" />
<xsl:text>-</xsl:text>
<xsl:call-template name="reverse-date">
<xsl:with-param name="text" select="substring-after($text, '-')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space($text)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
You'll need to change this:
<xsl:element name="date"><xsl:value-of select="@date"/></xsl:element>
To this:
<xsl:element name="date">
<xsl:call-template name="reverse-date">
<xsl:with-param name="text" select="@date" />
</xsl:call-template>
</xsl:element>