使用 XSLT 1.0 显示 X 个不同的随机节点集 [英] Display X distinct random node sets using XSLT 1.0

查看:21
本文介绍了使用 XSLT 1.0 显示 X 个不同的随机节点集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的 xsl 代码来显示一些动态 xml.

<xsl:for-each select="NewDataSet/Vehicle"><div class="item"><xsl:value-of select="ManufacturerName"/><br/><xsl:value-of select="Model"/><br/><xsl:value-of select="颜色"/><br/>£<xsl:value-of select='format-number(Price, "###,###,##0.")'/>

</xsl:for-each></xsl:模板>

我希望能够做的是显示 X 个随机不同节点集而不是所有节点集.这可以使用 xslt 1.0 吗?

谢谢.

解决方案

这是一个示例,展示了如何从给定的节点集中挑选 N 个随机节点.

您必须有一种方法来生成 0 到 1(不包括 1)之间的随机数才能使此工作正常进行.在此示例中,EXSLT math:random() 扩展函数用于此目的.如果您使用的是 MSXML 处理器,请将其替换为如下所示的扩展函数:https://stackoverflow.com/a/6607235/3016153

XML

<item id="1">001</item><item id="2">002</item><item id="3">003</item><item id="4">004</item><item id="5">005</item><item id="6">006</item><item id="7">007</item><item id="8">008</item><item id="9">009</item><item id="10">010</item><item id="11">011</item><item id="12">012</item></list>

XSLT 1.0

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/><xsl:template match="/list"><输出><xsl:call-template name="pick-random"><xsl:with-param name="node-set" select="item"/><xsl:with-param name="quota" select="5"/></xsl:call-template></xsl:模板><xsl:template name="pick-random"><xsl:param name="节点集"/><xsl:param name="quota"/><xsl:param name="selected" select="dummy-node"/><xsl:when test="count($selected) &lt; $quota and $node-set"><xsl:variable name="set-size" select="count($node-set)"/><xsl:variable name="rand" select="floor(math:random() * $set-size) + 1"/><!-- 递归调用--><xsl:call-template name="pick-random"><xsl:with-param name="node-set" select="$node-set[not(position()=$rand)]"/><xsl:with-param name="quota" select="$quota"/><xsl:with-param name="selected" select="$selected | $node-set[$rand]"/></xsl:call-template></xsl:when><xsl:否则><xsl:copy-of select="$selected"/></xsl:否则></xsl:选择></xsl:模板></xsl:stylesheet>

结果(示例运行)

注意:此方法保留所选项目的内部顺序.

I've got a simple xsl code to display some dynamically xml.

<xsl:template match="/">
  <xsl:for-each select="NewDataSet/Vehicle">
    <div class="item"> 
        <xsl:value-of select="ManufacturerName" /><br />
        <xsl:value-of select="Model" /><br />
        <xsl:value-of select="Colour" /><br />
        £<xsl:value-of select='format-number(Price, "###,###,##0.")' /> 
    </div>
  </xsl:for-each>
</xsl:template>

What I'd like to be able to do is display X number of random distinct node sets instead of all of them. Is this possible using xslt 1.0?

Thanks.

解决方案

Here is an example that shows how to pick N random nodes out of a given node-set.

You must have a method to generate a random number between 0 and 1 (not including 1) to make this work. In this example, the EXSLT math:random() extension function is used for this purpose. If you are using the MSXML processor, replace this with an extension function as shown here: https://stackoverflow.com/a/6607235/3016153

XML

<list>
    <item id="1">001</item>
    <item id="2">002</item>
    <item id="3">003</item>
    <item id="4">004</item>
    <item id="5">005</item>
    <item id="6">006</item>
    <item id="7">007</item>
    <item id="8">008</item>
    <item id="9">009</item>
    <item id="10">010</item>
    <item id="11">011</item>
    <item id="12">012</item>
</list>

XSLT 1.0

<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:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/list">
    <output>
        <xsl:call-template name="pick-random">
            <xsl:with-param name="node-set" select="item"/>
            <xsl:with-param name="quota" select="5"/>
        </xsl:call-template>
    </output>
</xsl:template>

<xsl:template name="pick-random">
    <xsl:param name="node-set"/>
    <xsl:param name="quota"/>
    <xsl:param name="selected" select="dummy-node"/>    
    <xsl:choose>
        <xsl:when test="count($selected) &lt; $quota and $node-set">
            <xsl:variable name="set-size" select="count($node-set)"/>    
            <xsl:variable name="rand" select="floor(math:random() * $set-size) + 1"/>       
            <!-- recursive call -->
            <xsl:call-template name="pick-random">
                <xsl:with-param name="node-set" select="$node-set[not(position()=$rand)]"/>
                <xsl:with-param name="quota" select="$quota"/>
                <xsl:with-param name="selected" select="$selected | $node-set[$rand]"/>         
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:copy-of select="$selected"/>
        </xsl:otherwise>
     </xsl:choose>
</xsl:template>

</xsl:stylesheet>

Result (of an example run)

<?xml version="1.0" encoding="UTF-8"?>
<output>
   <item id="1">001</item>
   <item id="3">003</item>
   <item id="8">008</item>
   <item id="10">010</item>
   <item id="12">012</item>
</output>

Note: This method preserves the internal order of the selected items.

这篇关于使用 XSLT 1.0 显示 X 个不同的随机节点集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆