随机选择 XSLT 中的一个节点

发布于 2024-08-04 06:02:11 字数 831 浏览 4 评论 0原文

我有一个关于 XSLT 中某种 af 随机函数的问题。

我有一个非常简化的 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 工作,如果这对你们有帮助的话。

谢谢, -金

I have a question about some sort af random function in XSLT.

I have an XML-file that very simplified look similar to this:

<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>

I would like to have some XSLT, that ramdomly took one of the nodes id's and put it into a variable called "choosenNode".
Like this, if the node with the ID of 1207 was the selected one:

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

How can i do this? Is there a random-function in XSLT?
By the way, I would like the variable to be refreshed on every page where the XSLT is included.

And I work in Umbraco CMS, if that helps you guys.

Thanks,
-Kim

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

笑咖 2024-08-11 06:02:11

在 Umbraco 中你可以做这样的事情:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:Stylesheet [ <!ENTITY nbsp " "> ]>
<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>

希望这有帮助。

蒂姆

In Umbraco you can do something like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:Stylesheet [ <!ENTITY nbsp " "> ]>
<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>

Hope this helps.

Tim

稚然 2024-08-11 06:02:11

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

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

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

Getting random number in xslt is not an easy task.

There's something that can do it but you probably has to provide seed for random generator
http://fxsl.sourceforge.net/articles/Random/Casting%20the%20Dice%20with%20FXSL-htm.htm

Maybe the processor you are using to do xsl transformation has ability to extend xsl expressions with outside functions. In that case maybe you can use outside random function.

dawn曙光 2024-08-11 06:02:11

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

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

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

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

All you need is a random number generator. There is none in XSLT thus the random number must be provided by something outside of XSLT. You will need to call a method from an external library to do this and the implemention of this library will depend on if you're on Windows (.NET or WIN32) or Linux and the XSLT processor.
XSLT can do math but it lacks a lot of date/time related functions which happens to include a random number generator.

However, XSLT does have a XPath function called generate-id() which will generate an unique ID. If you could transform this to a nuimber somehow, it might be used to create a random number, although it would be predictable and some numbers might occur more often than others. I wouldn't use it.

If you use MSXSL to process your stylesheet then you can include JavaScript to generate random numbers within the stylesheet. (Or C# script when using .NET.)

Getting the node itself is easy, once you know the number of child nodes. Just ask for the node at the random position. Something like /node/node[5] would return the 5th node.

(り薆情海 2024-08-11 06:02:11

该解决方案在使用 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 取出唯一的随机列表的第一行。

This solution works in a shell script that uses xsltproc and text utilities.

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

It's assumed that the style.xsl file will select the required element set and return it's values, one per line in the output text file. The tr command should put each element onto a separate line. The sort -uR should produce a unique, random list of the elements selected by the style.xsl style sheet commands. The head -n 1 then pulls out the first line of the unique, random list.

奶气 2024-08-11 06:02:11

下面假设 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:variable 元素的“value”属性,请尝试使用以下属性模板:

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

The following assumes the XSLT processor supports EXSLT extensions (e.g., xsltproc).

This will return the content of the randomly selected "node" (it must be a child of a "node", i.e. a "node/node" element).

<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>

This might be a useful snippet to process the content of the selected node:

<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>

Note that the above does not return the xslt definition of the variable, it uses that variable to copy the selected node.

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

<xsl:variable name='chosenNode' value='{node[position() = $selected]/@id}'/>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文