使用 XSLT 1.0 显示 X 个不同的随机节点集
Display X distinct random node sets using XSLT 1.0
我有一个简单的 xsl 代码来动态显示一些 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>
我想做的是显示 X 个随机不同的节点集,而不是显示所有节点集。这可能使用 xslt 1.0 吗?
谢谢。
这是一个示例,说明如何从给定的节点集中挑选 N 个随机节点。
您必须有一种方法来生成介于 0 和 1(不包括 1)之间的随机数,才能使此工作正常进行。在此示例中,EXSLT math:random() 扩展函数用于此目的。如果您使用的是 MSXML 处理器,请将其替换为如下所示的扩展函数:
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) < $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>
结果(示例运行)
<?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>
注意:此方法保留所选项目的内部顺序。
我有一个简单的 xsl 代码来动态显示一些 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>
我想做的是显示 X 个随机不同的节点集,而不是显示所有节点集。这可能使用 xslt 1.0 吗?
谢谢。
这是一个示例,说明如何从给定的节点集中挑选 N 个随机节点。
您必须有一种方法来生成介于 0 和 1(不包括 1)之间的随机数,才能使此工作正常进行。在此示例中,EXSLT math:random() 扩展函数用于此目的。如果您使用的是 MSXML 处理器,请将其替换为如下所示的扩展函数:
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) < $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>
结果(示例运行)
<?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>
注意:此方法保留所选项目的内部顺序。