2009-09-07 121 views
7

我對XSLT中的某種隨機函數有疑問。隨機選擇XSLT中的節點

我有一個XML文件是非常簡單的類似於此:

<node id="1198"> 
    <node id="1201"> 
    <data alias="name">Flemming</data> 
    <data alias="picture">1200</data> 
    </node> 
    <node id="1207"> 
    <data alias="name">John</data> 
    <data alias="picture">1205</data> 
    </node> 
    <node id="1208"> 
    <data alias="name">Michael</data> 
    <data alias="picture">1206</data> 
    </node> 
</node> 

我想有一些XSLT,那ramdomly了節點ID的一個,放入一個所謂的「choosenNode變量」。 這樣,如果與1207的ID的節點被選擇的一個:

<xsl:variable name="choosenNode" value="1207" /> 

我怎樣才能做到這一點? XSLT中是否有隨機函數?順便說一下,我希望在每個包含XSLT的頁面上刷新變量。

我在Umbraco CMS工作,如果這可以幫助你們。

感謝, -Kim

回答

7

在一把umbraco你可以做這樣的事情:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE xsl:Stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]> 
<xsl:stylesheet 
version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:msxml="urn:schemas-microsoft-com:xslt" 
xmlns:umbraco.library="urn:umbraco.library" 
xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" 
exclude-result-prefixes="msxml umbraco.library Exslt.ExsltMath"> 

<xsl:output method="xml" omit-xml-declaration="yes"/> 

<xsl:param name="currentPage"/> 

<!-- This should probably be a macro parameter so you can use this elsewhere--> 
<xsl:variable name="parentNode" select="1048"/> 

<xsl:template match="/"> 

     <xsl:variable name="numberOfNodes" select="count(umbraco.library:GetXmlNodeById($parentNode)/node)"/> 

     <xsl:variable name="randomPosition" select="floor(Exslt.ExsltMath:random() * $numberOfNodes) + 1"/> 

     <xsl:variable name="randomNode" select="umbraco.library:GetXmlNodeById($parentNode)/node [position() = $randomPosition]"/> 

     <!-- 
      You now have the node in the $randomNode variable 
      If you just want the id then you can do an XPath query on the variable 
      or you can modify the XPath above to get the property you are after rather than 
      the whole node 
     --> 

    <xsl:value-of select="$randomNode/@nodeName" /> 

</xsl:template> 
</xsl:stylesheet> 

希望這有助於。

Tim

+0

Tim看起來很酷,這可能是一個很好的解決方案。我會明天檢查出來,所以如果它能正常工作,你會得到一個正確的答案:D 謝謝... – 2009-09-07 15:24:58

+0

好的 - 我沒有真正檢查過代碼 - 只是輸入了它,幾乎離開了我的頭頂,所以要小心錯誤! – 2009-09-07 15:27:51

+0

OOOPS - 在那裏有幾個小錯別字。我已經整理過它並檢查了它是否適用於我的一個Umbraco安裝。我還添加了一行顯示如何獲取值。 – 2009-09-07 15:46:46

0

獲取XSLT中的隨機數是不容易的事。

有什麼東西可以做,但你可能已經爲隨機生成 http://fxsl.sourceforge.net/articles/Random/Casting%20the%20Dice%20with%20FXSL-htm.htm

也許你正在使用做XSL轉換處理器必須與外部功能擴展XSL表達能力提供種子。在這種情況下,也許你可以使用外部隨機功能。

+0

一把umbraco訪問其自身的擴展功能和XSLT處理器內部的微軟那些庫,所以該問題已解決。儘管XSLT處理器內部的腳本可以敲擊服務器 – 2009-09-07 18:50:46

0

所有你需要的是一個隨機數發生器。 XSLT中沒有任何內容,因此隨機數必須由XSLT之外的某些內容提供。您需要從外部庫調用一個方法來執行此操作,並且此庫的實現取決於您是在Windows(.NET或WIN32)還是Linux和XSLT處理器上。 XSLT可以做數學運算,但是它缺少很多與日期/時間相關的函數,這些函數碰巧包含一個隨機數生成器。

但是,XSLT確實有一個名爲generate-id()的XPath函數,它將生成一個唯一的ID。如果您可以以某種方式將其轉換爲裸人,它可能會用於創建一個隨機數字,儘管這是可以預測的,並且一些數字可能比其他數字更頻繁地出現。 我不會使用它。

如果您使用MSXSL來處理樣式表,那麼您可以包含JavaScript以在樣式表中生成隨機數。 (或使用.NET時的C#腳本)。

一旦知道了子節點的數量,獲取節點本身很容易。只需要在隨機位置詢問節點。像/ node/node [5]就會返回第5個節點。

0

此解決方案在使用xsltproc和文本實用程序的shell腳本中工作。

RandomElement=$(xsltproc style.xsl file.xml | tr ' ' '\n' | sort -uR | head -n 1) 

它假定style.xsl文件將選擇所需元素設置並返回它的值,每行一個輸出的文本文件。 tr命令應該將每個元素放在一個單獨的行上。 sort -uR應產生一個由style.xsl樣式表命令選擇的元素的唯一隨機列表。然後head -n 1抽出唯一隨機列表的第一行。

0

以下假定XSLT處理器支持EXSLT擴展(例如xsltproc)。

這將返回隨機選擇的「節點」(它必須是「節點」的子節點,即「節點/節點」元素)的內容。

<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 match="/"> 
    <xsl:apply-templates/> 
</xsl:template> 

<xsl:template match="node"> 
    <xsl:variable name='selected'> 
    <xsl:value-of select="ceiling(math:random() * count(node))"/> 
    </xsl:variable> 
    <xsl:copy-of select="node[position() = $selected]"/> 
</xsl:template> 
</xsl:stylesheet> 

這可能是一個有用的片段來處理所選節點的內容:

<xsl:variable name="randomNode" select="node[position() = $selectNode]"/> 
<id><xsl:value-of select="$randomNode/@id"/></id> 
<name><xsl:value-of select="$randomNode/data[@alias='name']"/></name> 
<picture><xsl:value-of select="$randomNode/data[@alias='picture']"/></picture> 

注意上面不返回變量的XSLT定義,它使用可變複製選定節點。

要設置一個xsl的「價值」屬性:可變元素,嘗試像一個屬性的模板:

<xsl:variable name='chosenNode' value='{node[position() = $selected]/@id}'/>