2014-02-22 101 views
1

我有一个包含这样的节点的XML文件:随机化节点顺序XSLT

<values> 
    <item>item 1</item> 
    <item>item 2</item> 
    <item>item 3</item> 
    <item>item 4</item> 
    <item>item 5</item> 
</values> 

我想使用XSLT来获得一个随机化的顺序列表:

<values> 
    <item>item 3</item> 
    <item>item 5</item> 
    <item>item 1</item> 
    <item>item 4</item> 
    <item>item 2</item> 
</values> 

我无法使用外部资源,如 “xmlns:java =”java.lang.Math“ and ”xmlns:math =“http://exslt.org/math”

由于限制。

也许这链接可能帮助:

http://fxsl.sourceforge.net/articles/Random/Casting%20the%20Dice%20with%20FXSL-htm.htm

+1

如果没有*一些*外部输入来提供“种子”(例如当前日期或时间),**任何**伪随机生成器在每次启动时都会产生相同的数字序列。如果满足这里随机化的目的,也许你可以简单地使用预先生成的随机数列表。 –

+0

我可以创建随机数并将它们输入到xslt中。 – CodePro

+0

你的意思是作为参数吗?那会很好。现在,你可以使用EXSLT node-set()函数吗? –

回答

5

以下样式表写在随机顺序的项目,以输出树。样式表需要在运行时将外部“初始种子”编号作为参数提供。

注意:由于这些项目只是在不进行处理的情况下重新排序,因此无需对它们进行排序,并且EXSLT node-set()函数毕竟不是必需的。

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/> 

<xsl:param name="initial-seed" select="123"/> 

<xsl:template match="/"> 
    <values> 
      <xsl:call-template name="pick-random-item"> 
       <xsl:with-param name="items" select="values/item"/> 
      </xsl:call-template> 
    </values> 
</xsl:template> 

<xsl:template name="pick-random-item"> 
    <xsl:param name="items" /> 
    <xsl:param name="seed" select="$initial-seed"/> 
    <xsl:if test="$items"> 
     <!-- generate a random number using the "linear congruential generator" algorithm --> 
     <xsl:variable name="a" select="1664525"/> 
     <xsl:variable name="c" select="1013904223"/> 
     <xsl:variable name="m" select="4294967296"/> 
     <xsl:variable name="random" select="($a * $seed + $c) mod $m"/> 
     <!-- scale random to integer 1..n --> 
     <xsl:variable name="i" select="floor($random div $m * count($items)) + 1"/> 
     <!-- write out the corresponding item --> 
     <xsl:copy-of select="$items[$i]"/> 
     <!-- recursive call with the remaining items --> 
     <xsl:call-template name="pick-random-item"> 
      <xsl:with-param name="items" select="$items[position()!=$i]"/> 
      <xsl:with-param name="seed" select="$random"/> 
     </xsl:call-template> 
    </xsl:if> 
</xsl:template> 

</xsl:stylesheet> 

应用到您的输入与所述默认的初始种子(123),则输出为:

<?xml version="1.0" encoding="utf-8"?> 
<values> 
    <item>item 2</item> 
    <item>item 3</item> 
    <item>item 1</item> 
    <item>item 4</item> 
    <item>item 5</item> 
</values> 

当与的1234种子进行时,输出为:

<?xml version="1.0" encoding="utf-8"?> 
<values> 
    <item>item 4</item> 
    <item>item 1</item> 
    <item>item 5</item> 
    <item>item 2</item> 
    <item>item 3</item> 
</values> 
+0

优秀的代码!谢谢! – CodePro