Udostępnij za pośrednictwem


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="https://www.w3.org/1999/XSL/Transform" 
    xmlns:msxml="urn:schemas-microsoft-com:xslt" 
    xmlns:random="https://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.

Comments

  • Anonymous
    April 20, 2009
    PingBack from http://asp-net-hosting.simplynetdev.com/random-number-generation-using-xslt/

  • Anonymous
    July 08, 2009
    Hi there, This is a really interesting concept that you have explained. I will try to see if I can get more information on this and how I can expand on this. Thanks for sharing. Cheers, Eddie Gear

  • Anonymous
    November 11, 2010
    Hi Mark, Very nice post! I've used this in a template where I need to show 3 random product groups (out of 7 groups in total). Is there a way to prevent the numbers from being the same number. Because when I get an output saying 177 it only shows the groups on position 1 and 7... :-)