2014-02-22 138 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