Skip to content

Instantly share code, notes, and snippets.

@greystate
Created February 23, 2011 00:33
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save greystate/839751 to your computer and use it in GitHub Desktop.
Save greystate/839751 to your computer and use it in GitHub Desktop.
Building a Multiplication Table with XSLT
<?xml version="1.0" encoding="utf-8"?>
<!--
Triggered by Darren Ferguson's hilarious "The Umbraco XSLT for loop"
(http://www.darren-ferguson.com/2011/2/22/the-umbraco-xslt-for-loop),
and Lee Kelleher's follow-up: http://pastebin.com/92UXcYUQ,
I thought I'd document the coolest way I've seen it done, which does not even use
recursion... only requirement is that the source document has at least as many "nodes"
as the loop needs.
(If there's too few nodes this stylesheet could be modified to use itself as "counter",
by using the document() function with an empty string - look it up :-)
Credit: The cool trick to use the nodes was something I saw in one of Jeni Tennison's books (d'uh - of course :-).
-->
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:output method="html" indent="yes" omit-xml-declaration="yes" doctype-system="about:legacy-compat" />
<xsl:variable name="nodes" select="//node() | //namespace::* | //comment() | //processing-instruction()" />
<xsl:template match="/">
<html>
<head>
<title>The Multiplication Table</title>
<style><![CDATA[
table { border-collapse: collapse; border: 2px solid #444; margin: 2em auto; }
caption { padding-bottom: 4px; letter-spacing: 1px; }
th, td { text-align: right; width: 2em; padding: 5px 2px; border-bottom: 1px solid #ccc; }
th { background: #ccc; padding-right: 4px; }
td:last-of-type { padding-right: 6px; }
]]></style>
</head>
<body>
<xsl:call-template name="create-table" />
</body>
</html>
</xsl:template>
<xsl:template name="create-table">
<table>
<caption>The Multiplication Table</caption>
<!-- for y = 1 to 10 -->
<xsl:for-each select="$nodes[position() &lt;= 10]">
<xsl:variable name="y" select="position()" />
<tr>
<th scope="row"><xsl:value-of select="$y" /></th>
<!-- for x = 2 to 10 -->
<xsl:for-each select="$nodes[position() &lt; 10]">
<xsl:variable name="x" select="position() + 1" />
<xsl:variable name="result" select="$y * $x" />
<td title="{$y} &#215; {$x} = {$result}"><xsl:value-of select="$result" /></td>
</xsl:for-each>
<!-- next x -->
</tr>
</xsl:for-each>
<!-- next y -->
</table>
</xsl:template>
</xsl:stylesheet>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment