7

我对 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,随机取一个节点 id 并将其放入一个名为“choosenNode”的变量中。像这样,如果选择了 ID 为 1207 的节点:

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

我怎样才能做到这一点?XSLT 中有随机函数吗?顺便说一句,我希望在包含 XSLT 的每个页面上刷新该变量。

我在 Umbraco CMS 工作,如果这对你们有帮助的话。

谢谢,-金

4

5 回答 5

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>

希望这可以帮助。

蒂姆

于 2009-09-07T15:13:41.547 回答
0

在 xslt 中获取随机数并不是一件容易的事。

有些东西可以做到,但你可能必须为随机生成器提供种子 http://fxsl.sourceforge.net/articles/Random/Casting%20the%20Dice%20with%20FXSL-htm.htm

也许您用于进行 xsl 转换的处理器能够使用外部函数扩展 xsl 表达式。在这种情况下,也许您可​​以使用外部随机函数。

于 2009-09-07T12:19:57.467 回答
0

您只需要一个随机数生成器。XSLT 中没有,因此随机数必须由 XSLT 之外的东西提供。您需要从外部库调用一个方法来执行此操作,该库的实现将取决于您使用的是 Windows(.NET 或 WIN32)还是 Linux 和 XSLT 处理器。XSLT 可以做数学运算,但它缺少很多与日期/时间相关的函数,而这些函数恰好包括一个随机数生成器。

但是,XSLT 确实有一个名为generate-id()的 XPath 函数,它将生成一个唯一的 ID。如果您可以以某种方式将其转换为数字,则它可能会用于创建随机数,尽管它是可预测的,并且某些数字可能比其他数字更频繁地出现。我不会用它。

如果您使用 MSXSL 处理样式表,则可以包含 JavaScript 以在样式表中生成随机数。(或使用 .NET 时的 C# 脚本。)

一旦您知道子节点的数量,获取节点本身就很容易。只需询问随机位置的节点即可。/node/node[5] 之类的东西会返回第 5 个节点。

于 2009-09-07T12:51:57.570 回答
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拉出唯一的随机列表的第一行。

于 2012-08-28T19:55:54.350 回答
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 定义,它使用该变量来复制选定的节点。

To set the 'value' attribute of an xsl:variable element, try an attribute template like:

<xsl:variable name='chosenNode' value='{node[position() = $selected]/@id}'/>
于 2012-08-28T21:23:20.117 回答