What are the pros and cons of functions vs templates in XSLT?
I want to send a unix-timestamp and get an answer like "today" or "tomorrow" or "next week". Which method is most appropriate for this?
What are the pros and cons of functions vs templates in XSLT?
I want to send a unix-timestamp and get an answer like "today" or "tomorrow" or "next week". Which method is most appropriate for this?
The main reason of choosing an <xsl:function>
over a named template is the much greater degree of composability of a function.
It is very easy and convenient to write an <xsl:function>
that produces the wanted results:
<xsl:function name="my:when" as="xs:string">
<xsl:param name="pDateTime" as="xs:dateTime"/>
<xsl:sequence select=
"for $vToday in xs:dateTime(current-date()),
$vTomorrow in $vToday
+ xs:dayTimeDuration('P1D'),
$vDayAfterTomorrow in $vTomorrow
+ xs:dayTimeDuration('P1D'),
$vNextWeek in $vToday
+ 7* xs:dayTimeDuration('P1D'),
$vNextFortnight in $vNextWeek
+ 7* xs:dayTimeDuration('P1D')
return
if($pDateTime lt $vToday)
then 'in the Past'
else if($pDateTime lt $vTomorrow)
then 'Today'
else if($pDateTime lt $vDayAfterTomorrow)
then 'Tomorrow'
else if($pDateTime lt $vNextWeek)
then 'This week'
else if($pDateTime lt $vNextFortnight)
then 'Next week'
else 'In the Future'
"/>
</xsl:function>
Here is a complete transformation:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:sequence select="my:when(current-dateTime())"/>,
<xsl:sequence select="my:when(current-dateTime()
+xs:dayTimeDuration('P1D'))"/>,
<xsl:sequence select="my:when(current-dateTime()
+xs:dayTimeDuration('P2D'))"/>,
<xsl:sequence select="my:when(current-dateTime()
+xs:dayTimeDuration('P3D'))"/>,
<xsl:sequence select="my:when(current-dateTime()
+xs:dayTimeDuration('P4D'))"/>,
<xsl:sequence select="my:when(current-dateTime()
+xs:dayTimeDuration('P5D'))"/>,
<xsl:sequence select="my:when(current-dateTime()
+xs:dayTimeDuration('P6D'))"/>,
<xsl:sequence select="my:when(current-dateTime()
+xs:dayTimeDuration('P7D'))"/>,
<xsl:sequence select="my:when(current-dateTime()
+xs:dayTimeDuration('P8D'))"/>,
<xsl:sequence select="my:when(current-dateTime()
+xs:dayTimeDuration('P9D'))"/>
</xsl:template>
<xsl:function name="my:when" as="xs:string">
<xsl:param name="pDateTime" as="xs:dateTime"/>
<xsl:sequence select=
"for $vToday in xs:dateTime(current-date()),
$vTomorrow in $vToday
+ xs:dayTimeDuration('P1D'),
$vDayAfterTomorrow in $vTomorrow
+ xs:dayTimeDuration('P1D'),
$vNextWeek in $vToday
+ 7* xs:dayTimeDuration('P1D'),
$vNextFortnight in $vNextWeek
+ 7* xs:dayTimeDuration('P1D')
return
if($pDateTime lt $vToday)
then 'in the Past'
else if($pDateTime lt $vTomorrow)
then 'Today'
else if($pDateTime lt $vDayAfterTomorrow)
then 'Tomorrow'
else if($pDateTime lt $vNextWeek)
then 'This week'
else if($pDateTime lt $vNextFortnight)
then 'Next week'
else 'In the Future'
"/>
</xsl:function>
</xsl:stylesheet>
when this transformation is applied (to any document -- not used), the wanted, correct result is produced:
Today,
Tomorrow,
This week,
This week,
This week,
This week,
This week,
Next week,
Next week,
Next week
In this case, an external function is best-suited.
XSLT is best suited for pattern matching and transformation, not computation.