Home

Algorithmic Advent: 22 – XSLT transformation of custom format to HTML

Published on 22 Dec 2010. Tagged with algorithmicadvent.

The following example generates HTML output from a custom XML format. In this case, the format describes some kind of a time-table. You should be able to view a rendered HTML document if you open the xml file in a capable browser (e.g. Firefox).

test.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="myformat_to_xhtml.xsl"?>
<myformat>
    <day>
        <course hour="8">Physics</course>
        <course hour="9">Physics</course>
        <course hour="10">Physics</course>
    </day>
    <day>
        <course hour="12">English</course>
        <course hour="13">English</course>
        <course hour="14">English</course>
    </day>
    <day>
        <course hour="14">Maths</course>
        <course hour="15">Maths</course>
        <course hour="16">Maths</course>
    </day>
    <day>
        <course hour="11">Computer Science</course>
        <course hour="12">Computer Science</course>
        <course hour="14">Computer Science</course>
    </day>
    <day>
        <course hour="8">Sports</course>
        <course hour="10">Sports</course>
        <course hour="16">Sports</course>
    </day>
</myformat>

myformat_to_xhtml.xsl

<?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="row">
        <xsl:param name="count" select="1"/>

        <xsl:if test="$count &lt;= 16">
            <tr>
                <td><xsl:value-of select="$count" /></td>
                <xsl:for-each select="/myformat/day">
                    <td>
                    <xsl:choose>
                        <xsl:when test="course[@hour=$count]">
                            <xsl:value-of select="course[@hour=$count]" />
                        </xsl:when>
                        <xsl:otherwise>-</xsl:otherwise>
                    </xsl:choose>
                    </td>
                </xsl:for-each>
            </tr>
            <xsl:call-template name="row">
                <xsl:with-param name="count" select="$count + 1"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

    <xsl:template match="/">
        <html>
            <head>
                <title>myformat_to_xhtml.xsl</title>
            </head>
            <body>
                <table border="1">
                    <tr>
                        <th>#</th>
                        <th>Monday</th>
                        <th>Tuesday</th>
                        <th>Wednesday</th>
                        <th>Thursday</th>
                        <th>Friday</th>
                    </tr>

                    <xsl:call-template name="row">
                        <xsl:with-param name="count" select="8"/>
                    </xsl:call-template>
                </table>
            </body>
        </html>
    </xsl:template>

</xsl:stylesheet>