ianyoung
ianyoung

Reputation: 3035

XSLT: Select a random item from range and output its attributes

Using XSLT 1.0 I need to define a list of items assigned to a variable and pull out a random item and refer to it's attributes in a HTML block.

I'm thinking that I essentially need to:

1) Define the list of items
2) Select one at random
3) Pull out the attributes of the randomly selected item into my HTML

The Output HTML part is pseudo-code at the moment but here's what I have so far. I'd appreciate any pointers or suggestions to get this working.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:math="http://exslt.org/math"
    extension-element-prefixes="math">

<xsl:template name="item">

    <!-- List of items -->
    <xsl:variable name="items" as="element()*">
        <item name="item-one" link="http://www.website.com" />
        <item name="item-two" link="http://www.website.com" />
        <item name="item-two" link="http://www.website.com" />
    </xsl:variable>

    <!-- Select item at random and assign to variable -->
    <xsl:variable name="random-item">
        <xsl:value-of select="$items[(floor(math:random()*2) mod 2) + 1]" />
    </xsl:variable>

    <!-- Output -->
    <div class="item">
        <a href="${item-link}" >
            <picture>
                <source srcset="/images/${item-name}.gif" media="(min-width: 1280px)" />
                <source srcset="/images/${item-name}.gif" media="(min-width: 768px)" />
                <img src="/images/${item-name}.gif" />
            </picture>
        </a>
    </div>

</xsl:template>

Thanks.

Upvotes: 0

Views: 930

Answers (1)

ianyoung
ianyoung

Reputation: 3035

Here's what I eventually came up with. Updated here as it may be of use to someone else.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:math="http://exslt.org/math"
    extension-element-prefixes="math">

<xsl:template name="item">

    <!-- List of items -->
    <xsl:variable name="items">
        <item name="item-one" link="http://www.website.com">Item 1</item>
        <item name="item-two" link="http://www.website.com">Item 2</item>
        <item name="item-three" link="http://www.website.com">Item 3</item>
    </xsl:variable>

    <!-- Intermediate inline data model. All that's available in XSLT 1.0 -->
    <xsl:param name="array" select="document('')/*/xsl:variable[@name='items']/*" />

    <!-- Random number (based on number of items in list above) -->
    <xsl:variable name="random-number" select="(floor(math:random()*3) mod 3) + 1" />

    <!-- Item attributes (of the randomly selected item) -->
    <xsl:variable name="item-name" select="$array[number($random-number)]/@name" />
    <xsl:variable name="item-link" select="$array[number($random-number)]/@link" />
    <xsl:variable name="item-alt" select="$array[number($random-number)]" />

    <!-- Output (using attribute value templates) -->
    <div class="item">
        <a href="{$item-link}" >
            <picture>
                <source srcset="/images/{$item-name}.png" media="(min-width: 1280px)" />
                <source srcset="/images/{$item-name}.png" media="(min-width: 768px)" />
                <img src="/images/{$item-name}" alt="{$item-alt}" />
            </picture>
        </a>
    </div>

</xsl:template>

This example is tested and working

Upvotes: 1

Related Questions