使用XSL从XML中随机获取节点

时间:2013-06-19 12:19:43

标签: html xml xslt

我正在使用CMS创建一个网站,在主页中我需要随机获取一些图片和描述,每次刷新页面以获取新节点时我都需要。

这就是我在XSL中调用节点的方式:

<xsl:for-each select ="TSPRoot/Blocks/Block[@ID=134]/Articles/Article[position() &lt; 4]">
          <div class="layout-08">
            <a class="title" href="detailed.aspx?id={ID}">
              <xsl:choose >
                <xsl:when test ="string-length(ImageURL) > 0">
                  <img src="_handlers/resizeimage.ashx?src={ImageURL}&amp;height=149&amp;width=206" title="{Headline}"/>
                </xsl:when>
                <xsl:otherwise>
                  <img src="_frontend/ux/images/en_logo.png" width="206" height="149" title="{Headline}"/>
                </xsl:otherwise>
              </xsl:choose>
            </a>
            <div class="bg">
              <a href="detailed.aspx?id={ID}"><xsl:value-of select ="Headline"/></a>
            </div>
          </div>
        </xsl:for-each>

这得到最新的(3)节点,每次刷新时我都需要随机(3)节点。

1 个答案:

答案 0 :(得分:0)

我只会给你一些可能解决方案的想法。 从技术上讲,XSLT不提供方法随机数。但是,这个问题至少可以通过三种不同的方式解决:

  1. 在执行XSLT模板之前,在Java / C#/ PHP代码中生成伪随机数,并将生成的数字作为XSLT参数传递。
  2. 使用扩展功能:http://exslt.org/random/functions/random-sequence/index.html

  3. 使用current-dateTime()(XSLT 2.0)函数作为随机数过程的种子。通过几个字符串和数学运算,您可以将其转换为所需的准随机数。我认为根据您的需求,这个解决方案就足够了。

  4. 编辑 - 广告3。

    我已经用这个想法做了一些实验。我已经创建了一些示例代码。我知道这段代码生成了一系列真正的随机数,但对于简单的网页,就像在问题中它可能已经足够了。

    以下XSLT:

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:rnd="http://whatever.org/random">
        <xsl:output indent="yes" />
        <xsl:function name="rnd:pseudoRandomInternal">
            <xsl:param name="numSeed" as="xs:decimal"/>
            <xsl:variable name="squareSeed" select="xs:string($numSeed*$numSeed)"/>
            <xsl:variable name="oneDivSeed" select="substring($squareSeed, 3, string-length($squareSeed) - 3)"/>
            <xsl:variable name="cc" select="if (string-length($oneDivSeed) > 6) then 
                substring($oneDivSeed, string-length($oneDivSeed) - 6) else 
                $oneDivSeed"/>
            <xsl:value-of select="xs:decimal($cc)"/>
        </xsl:function>
        <xsl:function name="rnd:pseudoRandom" as="xs:decimal*">
            <xsl:param name="range" as="xs:integer"/>
    
            <xsl:choose>
                <xsl:when test="$range = 1">
                    <xsl:variable name="seed" select="substring(xs:string(current-time()), 1, 12)" as="xs:string"/>
                    <xsl:variable name="numSeed" select="xs:decimal(translate($seed, ':.+-', ''))"/>
                    <xsl:sequence select="(rnd:pseudoRandomInternal($numSeed))" />
                </xsl:when>
                <xsl:otherwise>
                    <xsl:variable name="subSequence" select="rnd:pseudoRandom($range - 1)"/>
                    <xsl:variable name="newValue" select="rnd:pseudoRandomInternal($subSequence[1])" as="xs:decimal*"/>
                    <xsl:sequence select="($newValue, $subSequence)"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:function>
        <xsl:template match="/">
            <xsl:variable name="rr" select="rnd:pseudoRandom(10)" as="xs:decimal*"/>
    
            <output>
            <xsl:for-each select="$rr">
                <item>
                    <xsl:value-of select=". * 3 mod 11" />
                </item>
            </xsl:for-each>
            </output>
        </xsl:template>
    </xsl:stylesheet>
    

    生成以下输出:

    <output>
        <item>10</item>
        <item>9</item>
        <item>6</item>
        <item>9</item>
        <item>9</item>
        <item>10</item>
        <item>3</item>
        <item>5</item>
        <item>9</item>
        <item>4</item>
    </output>
    
相关问题