Random Number Generation using XSLT

Just whipped this up real quick since I needed for something and thought I’d share. If you’re using a Microsoft based XSLT processor and have a need to generate random numbers for some purpose, here’s a quick xsl snippet to help you out.

 <?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxml="urn:schemas-microsoft-com:xslt" 
    xmlns:random="http://www.microsoft.com/msxsl" 
    exclude-result-prefixes="msxml random">
    
    <xsl:output method="text"/>
    <msxml:script implements-prefix="random">
        function range(min, max) 
        { 
            var dist = max - min + 1;
            return Math.floor(Math.random() * dist + min);
        }
    </msxml:script>
    <xsl:template match="/">
        <xsl:call-template name="GenerateRandomNumbers">
            <xsl:with-param name="count">200</xsl:with-param>
        </xsl:call-template>
    </xsl:template>
    <xsl:template name="GenerateRandomNumbers">
        <xsl:param name="count"/>
        <xsl:param name="curIndex">0</xsl:param>
        <xsl:value-of select="random:range(0, 100)"/>
        <xsl:text>&#xD;</xsl:text>
        <xsl:if test="number($count) != (number($curIndex) + 1)">
            <xsl:call-template name="GenerateRandomNumbers">
                <xsl:with-param name="count">
                    <xsl:value-of select="$count"/>
                </xsl:with-param>
                <xsl:with-param name="curIndex">
                    <xsl:value-of select="string(number($curIndex) + 1)"/>
                </xsl:with-param>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

You’ll have to modify the stylesheet to suit your specific purpose. In this example, I’m simply generating a list of 200 random numbers between 0 and 100. The magic happens within the msxml:script element. A script element basically allows you to extend the XSL processor to support additional processing it wasn’t designed to do. In this case, since I’m using a Microsoft XSL processor, it’s using JScript as the scripting language. If you were to use Saxon however, you will more than likely use Java for the processor extension.

One more thing to note: As I mentioned earlier, I created this somewhat quickly ( a matter of minutes) and just went ahead and used recursion for looping. It should be noted that if you pass a large count value into the GenerateRandomNumbers template, it is possible to overflow the stack and prematurely exit out of the transformation. The key takeaway here it to use the msxml:script element that defines the random:range script function and to call it every once in awhile from a xsl:value-of instruction for example.