1

can someone tell me, how can I create a list of dates using xslt using a start- and end date and a parameter for the calculation period, so sth like the input

<root>
    <startdate>2014/01/01</startdate>
    <enddate>2015/02/20</enddate>
    <period>daily</period>
</root>

gives me a list

<root>
    <date>2014/01/01</date>
    <date>2014/01/02</date>
    ...
    <date>2014/02/20</date>
</root>

My node period can have values in

daily
weekly
fortnightly
monthly

So the last 3 would give me lists like

<root>
    <date>2014/01/01</date>
    <date>2014/01/08</date>
    ...
    <date>2015/02/18</date>
</root>

<root>
    <date>2014/01/01</date>
    <date>2014/01/15</date>
    ...
    <date>2015/02/11</date>
</root>

<root>
    <date>2014/01/01</date>
    <date>2014/02/01</date>
    ...
    <date>2015/02/01</date>
</root>

with the last date smaller or equal the enddate. The date formats I would use are YYYYMMDD and DD/MM/YYYY, but I would probably be able to adapt any other date format.

Someone knows how to do this?

Thanks very much!

Willi Fischer
  • 455
  • 6
  • 21

1 Answers1

3

First, you must use YYYY-MM-DD format if you want your dates to be recognized as such.

Now, here's a quick-and-dirty way to achieve the requested result:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:template match="/root">
    <result>
        <xsl:call-template name="enumerate-dates">
            <xsl:with-param name="startdate" select="startdate"/>
            <xsl:with-param name="enddate" select="enddate"/>
            <xsl:with-param name="period" select="period"/>
        </xsl:call-template>
    </result>
</xsl:template>

<xsl:template name="enumerate-dates">
    <xsl:param name="startdate" as="xs:date"/>
    <xsl:param name="enddate" as="xs:date"/>
    <xsl:param name="period"/>
    <xsl:if test="$startdate le $enddate">
        <date><xsl:value-of select="$startdate" /></date>
        <xsl:call-template name="enumerate-dates">
            <xsl:with-param name="startdate">
                <xsl:choose>
                    <xsl:when test="$period='daily'">
                        <xsl:value-of select="$startdate + xs:dayTimeDuration('P1D')" />
                    </xsl:when>
                    <xsl:when test="$period='weekly'">
                        <xsl:value-of select="$startdate + xs:dayTimeDuration('P7D')" />
                    </xsl:when>
                    <xsl:when test="$period='fortnightly'">
                        <xsl:value-of select="$startdate + xs:dayTimeDuration('P14D')" />
                    </xsl:when>
                    <xsl:when test="$period='monthly'">
                        <xsl:value-of select="$startdate + xs:yearMonthDuration('P1M')" />
                    </xsl:when>
                </xsl:choose>
            </xsl:with-param>
            <xsl:with-param name="enddate" select="$enddate"/>
            <xsl:with-param name="period" select="$period"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

Applied to an example input of:

<root>
    <startdate>2013-12-15</startdate>
    <enddate>2014-03-08</enddate>
    <period>fortnightly</period>
</root>

the result is:

<?xml version="1.0" encoding="utf-8"?>
<result>
   <date>2013-12-15</date>
   <date>2013-12-29</date>
   <date>2014-01-12</date>
   <date>2014-01-26</date>
   <date>2014-02-09</date>
   <date>2014-02-23</date>
</result>
michael.hor257k
  • 113,275
  • 6
  • 33
  • 51
  • +1 for generously answering a question that showed no attempt yet requested support for four (!) separate time increments. Good demo of recursion in XSLT too. – kjhughes Sep 23 '14 at 15:41
  • 1
    Thanks, very nice! kjhughes, plese forgive I did not mention what I had tried before. I was trying to loop and apply a condition to break the loop at some point, but this apparently is not a good idea in xslt at all, so I didnt mention it. – Willi Fischer Sep 23 '14 at 15:52