In a modern XSLT 3 implementation supporting the random-number-generator
function you can use e.g. random-number-generator()?permute(/xml/value)[position() = 1 to 3]
:
let $xml := <xml>
<value>A</value>
<value>B</value>
<value>C</value>
<value>D</value>
<value>E</value>
<value>F</value>
<value>G</value>
<value>H</value>
<value>I</value>
<value>J</value>
</xml>,
$values := $xml/value,
$length := xs:integer(count($values) * .3)
return random-number-generator()?permute($values)[position() = 1 to $length]
So you need an XSLT 3 processor like Saxon 10 in any edition or Saxon 9 PE or EE or AltovaXML 2017 R3 or later.
In XSLT 1, if you have support for EXSLT's math:random
, you can use
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:math="http://exslt.org/math">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="xml">
<xsl:copy>
<xsl:apply-templates select="value[position() < 4]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="value">
<xsl:copy>
<xsl:variable name="pos" select="floor(math:random() * 10 + 1)"/>
<xsl:value-of select="../value[$pos]"/>
</xsl:copy>
</xsl:template>
</xsl:transform>
http://xsltransform.net/93Fbify