Random Items in XSLT
Asked Answered
S

6

15

I'm customizing a Google Search appliance, which uses XSLT to present results to the user. Our design calls for one of several images to be included randomly on the results page. Is there a way to use randomness in XSLT? (Pseudo-randomness is just fine for this application.)

Calling random templates would be fine, as would just being able to generate a random number and branch based on that.

Shaggy answered 1/3, 2010 at 21:16 Comment(2)
Since the Search Appliance only seems interested in XSLT 1.0, I decided to go with using the length of the search string to determine which image gets displayed. Thus, I'm using something like this to get a 0-3 number range: <xsl:value-of select="string-length(/GSP/Q) mod 4"/>Shaggy
+1, good and practical work-around under the circumstances. I was going to write something similar as an answer before I read this.Ruthenium
C
5

Depending on your platform XSL allows inject of user code like C#. I don't recommend this. Better, I would have your XSL accept a parameter and whatever is generating your XML payload or XSLT and can also generate the random number, setting the parameter. I've done this exactly using this approach except the data came from Bing, not G.

Cowes answered 1/3, 2010 at 21:22 Comment(2)
How did you convince Bing to send you a random number? Or did you just take a query string or something and process it to get a number out of it? As far as I can tell, I don't have much control over the XML payload the Search Appliance generates.Shaggy
Randomness is generated by the bing API caller and the random number passed as a parameter. Bing gives you XML. You have an XSLT that accepts parameters. Merely bring buyer and seller together.Cowes
T
10

You can generate in pure XSLT sequences of random numbers and also random permutations of the numbers in [1 .. N].

Just use the FXSL library (written in pure XSLT) for this.

This article explains the templates to use and has complete examples:

"Casting the Dice with FXSL: Random Number Generation Functions in XSLT".

Trackman answered 2/3, 2010 at 2:12 Comment(0)
C
5

Depending on your platform XSL allows inject of user code like C#. I don't recommend this. Better, I would have your XSL accept a parameter and whatever is generating your XML payload or XSLT and can also generate the random number, setting the parameter. I've done this exactly using this approach except the data came from Bing, not G.

Cowes answered 1/3, 2010 at 21:22 Comment(2)
How did you convince Bing to send you a random number? Or did you just take a query string or something and process it to get a number out of it? As far as I can tell, I don't have much control over the XML payload the Search Appliance generates.Shaggy
Randomness is generated by the bing API caller and the random number passed as a parameter. Bing gives you XML. You have an XSLT that accepts parameters. Merely bring buyer and seller together.Cowes
C
4

If you use a Java based XSLT engine, this will allow you to make calls to any static method within the Java libraries, such as java.lang.Math.random(). Here is the syntax...

<?xml version='1.0'?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:math="java.lang.Math"
    version='1.1'>

    <xsl:template match="/">
        <xsl:variable name="myRandom" select="math:random()"/>
        <xsl:value-of select="$myRandom"/>
    </xsl:template>

</xsl:stylesheet>
Connatural answered 1/3, 2010 at 21:58 Comment(3)
PS - It has to be XSL version 1.1 or higher.Connatural
Cool trick! Unfortunately, the Search Appliance only seems interested in XSLT v1.0. Rats!Shaggy
Not available under Saxon HE, unfortunately. Would have been too good to be true.Intake
F
2

If you are not averse to including libraries, there are many available such as random:random-sequence from EXSLT

Freehanded answered 1/3, 2010 at 21:22 Comment(2)
Can't see using a library that implements random() when you have direct access to it via the run time environment.Connatural
@Connatural - but the OP doesn't have direct access to it via the run time envt.Nitid
K
1

If you are doing this for anything Microsoft, I found that using XSLT's function ddwrt:Random works.

I use the following to create the random number

<xsl:variable name="RowCount" select="count($Rows)" />
<xsl:variable name="RandomNumber" select="ddwrt:Random(1, $RowCount)" />

and the following to present

<xsl:for-each select="$Rows[position() = $RandomNumber]">
<xsl:value-of select="@Title" /></xsl:for-each>
Katerinekates answered 28/5, 2014 at 18:59 Comment(0)
P
0

The following simple solution greatly assisted me with XSLT 2 (generates random number):

sum(string-to-codepoints(generate-id($generated//random))

Or you can use it as a function:

<xsl:function name=“your:random-int" as="xs:integer">
  <xsl:variable name="generated">
    <random/>
  </xsl:variable>
  <xsl:value-of select="sum(string-to-codepoints(generate-id($generated//random)))"/>
</xsl:function>

Here's how it works:

  1. The generate-id() function generates a string containing the generated id, such as wfx2d123d8.
  2. The string-to-codepoints() function transforms the string obtained in the previous step into a list of nodes of ASCII codes of the string , similar to the following: (119, 102, 120, 50, 100, 49, 50, 51, 100, 56).
  3. Finally, the sum() function calculates the sum of all the numbers obtained in step 2, resulting in a single value

As you can observe, the random number generator mentioned is not reliable and lacks a uniform distribution. Therefore, I strongly advise against using it for important tasks. However, if you require a simple solution and are unconcerned about distribution, as was the case for me, it could potentially serve as an option.

Polytypic answered 6/7, 2023 at 13:21 Comment(4)
This method is entirely processor-dependent. The specification does NOT mandate that the generated id must be different each time a document is transformed. The fact remains that in XSLT 1.0 or 2.0 there is no way to generate random numbers. You must rely on an external method or, at the very least, supply a seed (in XSLT 2.0, this could be the current dateTime).Everetteverette
@michael.hor257k, Thank you for the comment. I would like to ask for your guidance. Could you please assist me in finding the exact location where I can supply a seed to generate a random number?Polytypic
The standard way to supply any value to the transformation at runtime is through a stylesheet parameter.Everetteverette
See an example (in XSLT 1.0, actually) here: https://mcmap.net/q/824074/-randomize-node-order-xsltEveretteverette

© 2022 - 2024 — McMap. All rights reserved.