Building-blocks logo. Incremental Development, Inc.

XSL example, XSLT example, XSL sample, XSLT sample, XSL tutorial, XSLT tutorial, stupid XSL trick, stupid XSLT trick.

Parvez's Wing of the Gallery of Stupid XSL and XSLT Tricks

This page is Muhammad Athar Parvez's wing of the Gallery of Stupid XSL and XSLT Tricks.

Calendar

These files together can produce calendar for any month. Only the parameters for generating the calendar are provided through the input file, otherwise the stylesheet has the complete logic.

Input, specifying the start day (1-7), days in the month (28-31), and title for the calendar.

<month start="3" days="31">
    <name>May 2001</name>
</month>

Stylesheet:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output method="xml" encoding="UTF-8"/>

<xsl:variable name="start" select="/month/@start"/>
<xsl:variable name="count" select="/month/@days"/>

<xsl:variable name="total" select="$start + $count - 1"/>
<xsl:variable name="overflow" select="$total mod 7"/>

<xsl:variable name="nelements">
    <xsl:choose>
        <xsl:when test="$overflow > 0"><xsl:value-of select="$total + 7 - $overflow"/></xsl:when>
        <xsl:otherwise><xsl:value-of select="$total"/></xsl:otherwise>
    </xsl:choose>
</xsl:variable>

<xsl:template match="/">

    <html>
    <head><title><xsl:value-of select="month/name"/></title></head>

    <body bgcolor="lightyellow">

    <h1 align="center"><xsl:value-of select="month/name"/></h1>

    <table summary="calendar" border="1" bgcolor="yellow" align="center">
        <tr bgcolor="white">
        <th>Sun</th><th>Mon</th><th>Tue</th><th>Wed</th><th>Thu</th><th>Fri</th><th>Sat</th>
        </tr>

        <xsl:call-template name="month"/>
    </table>

    </body></html>

</xsl:template>

<!-- Called only once for root -->
<!-- Uses recursion with index + 7 for each week -->
<xsl:template name="month">
    <xsl:param name="index" select="1"/>

    <xsl:if test="$index &lt; $nelements">
        <xsl:call-template name="week">
            <xsl:with-param name="index" select="$index"/>
        </xsl:call-template>

        <xsl:call-template name="month">
            <xsl:with-param name="index" select="$index + 7"/>
        </xsl:call-template>
    </xsl:if>

</xsl:template>

<!-- Called repeatedly by month for each week -->
<xsl:template name="week">
    <xsl:param name="index" select="1"/>
    <tr>
        <xsl:call-template name="days">
            <xsl:with-param name="index" select="$index"/>
            <xsl:with-param name="counter" select="$index + 6"/>
        </xsl:call-template>
    </tr>
</xsl:template>

<!-- Called by week -->
<!-- Uses recursion with index + 1 for each day-of-week -->
<xsl:template name="days">
    <xsl:param name="index" select="1"/>
    <xsl:param name="counter" select="1"/>

    <xsl:choose>
        <xsl:when test="$index &lt; $start">
            <td>-</td>
        </xsl:when>

        <xsl:when test="$index - $start + 1 > $count">
            <td>-</td>
        </xsl:when>

        <xsl:when test="$index > $start - 1">
            <td><xsl:value-of select="$index - $start + 1"/></td>
        </xsl:when>

    </xsl:choose>

    <xsl:if test="$counter > $index">
        <xsl:call-template name="days">
            <xsl:with-param name="index" select="$index + 1"/>
            <xsl:with-param name="counter" select="$counter"/>
        </xsl:call-template>
    </xsl:if>

</xsl:template>

</xsl:stylesheet>

Output looks like this in a browser:

May 2001

Sun Mon Tue Wed Thu Fri Sat
- - 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31 - -

The actual HTML output:

<html>
 <head>
  <title>May 2001</title>
 </head>
 <body bgcolor="lightyellow">
  <h1 align="center">May 2001</h1>
  <table align="center" bgcolor="yellow" border="1">
   <tr bgcolor="white">
    <th>Sun</th><th>Mon</th><th>Tue</th><th>Wed</th><th>Thu</th><th>Fri</th><th>Sat</th>
   </tr>
   <tr>
    <td>-</td><td>-</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td>
   </tr>
   <tr>
    <td>6</td><td>7</td><td>8</td><td>9</td><td>10</td><td>11</td><td>12</td>
   </tr>
   <tr>
    <td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td>
   </tr>
   <tr>
    <td>20</td><td>21</td><td>22</td><td>23</td><td>24</td><td>25</td><td>26</td>
   </tr>
   <tr>
    <td>27</td><td>28</td><td>29</td><td>30</td><td>31</td><td>-</td><td>-</td>
   </tr>
  </table>
 </body>
</html>