1

I want to select 30% of values randomly from a XML.As Here is 10 values so , i have to select 3 values randomly.

i have a 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>

I need this value.

<xml>
    <value>E</value>
    <value>I</value>
    <value>J</value>
</xml>
Rudraprasad Pradhan
  • 181
  • 1
  • 1
  • 12

1 Answers1

0

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() &lt; 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

Martin Honnen
  • 160,499
  • 6
  • 90
  • 110