📜 ⬆️ ⬇️

Random sorting and output of random elements in XSLT

Introduction


In this article I want to share with you my attempts to create a random (although it would be more appropriate to say pseudo-random) sorting with XSLT, without using third-party applications and extensions.

Initially, the task was to do the sorting for a PHP XSLT processor. But I wanted to do something more universal.

Prototype


First we need a sample to test the sorting. We will not be engaged in artful designs and we will write simply.
')
Data file data.xml
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="view.xsl"?> <root> <item id="1"/><item id="2"/><item id="3"/><item id="4"/><item id="5"/><item id="6"/><item id="7"/><item id="8"/><item id="9"/><item id="10"/> </root> 


We generate randomness


In order to randomly sort something, you need to have something random at hand. And nothing is better than the generate-id () function, which returns the unique identifier of an element as a string.

Let's see what we get with different processors that were at hand.

View.xsl conversion file
 <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html"/> <xsl:template match="/"> <xsl:for-each select="/root/item"> <xsl:value-of select="generate-id()"/><br/> </xsl:for-each> </xsl:template> </xsl:stylesheet> 

Result
PhpFirefoxOperaMsxmlSafari
id1690783id0xfd238240op5275038IDAKA0MBidp100503080
id1690785id0xfd2383d0op5275022IDAMA0MBidp100502144
id1690788id0xfd238470op5275006IDAOA0MBidp100502072
id1690789id0xfd2384c0op5274990IDAQA0MBidp100502936
id1690787id0xfd238510op5274974IDASA0MBidp100502792
id1690784id0xfd2640b0op5274958IDAUA0MBidp100502648
id1690782id0xfd2641f0op5274942IDAWA0MBidp125378088
id1690779id0xfd264240op5274926IDAYA0MBidp100502504
id1690777id0xfd264330op5274910IDA0A0MBidp125377944
id1690775id0xfd2643d0op5274894IDA2A0MBidp100503224

Looking at the table, you can see two troubles: the identifiers go in a certain order and each XSLT processor generates an identifier under its own way. I can not write about melkomyagkih, and then stood out.

Random sort


I will not describe my unsuccessful attempts to transform the sequence into randomness, test different algorithms, the amount of alcohol drunk and sleepless nights. I will write what happened as a result.

View.xsl conversion file
 <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html"/> <xsl:template match="/"> <xsl:for-each select="/root/item"> <xsl:sort select="translate(generate-id(), 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', '0192834765019283476501928347650192834765019283476501') mod 3.1415" data-type="number"/> <xsl:value-of select="@id"/><br/> </xsl:for-each> </xsl:template> </xsl:stylesheet> 

The main element here is the “select” attribute of the “xsl: sort” element. So let's proceed to the analysis: the unique identifier of the current element is taken (using the “generate-id ()” function), all alphabetic values ​​are replaced with digital values ​​(using the “translate ()” function) and the result is divided by the module by the Pi number ( why it was Pi, what first came to mind).

Although not pulling on the perfect and elegant solution, it works.

The output of a certain number of random elements.


We modify the table to display a certain number of random elements from the set. The function of determining the number of the current position () element will help us in this. Let's deduce 4 random elements.

View.xsl conversion file
 <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html"/> <xsl:template match="/"> <xsl:for-each select="/root/item"> <xsl:sort select="translate(generate-id(), 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', '0192834765019283476501928347650192834765019283476501') mod 3.1415" data-type="number"/> <xsl:if test="position() &lt; 5"> <xsl:value-of select="@id"/><br/> </xsl:if> </xsl:for-each> </xsl:template> </xsl:stylesheet>. 

Some PHP


Since at the beginning of the article it was mentioned about PHP, then I’ll finish with code for conversion in this language.
 <?php $data = new DOMDocument('1.0', 'UTF-8'); $data->load('data.xml'); $view = new DOMDocument('1.0', 'UTF-8'); $view->load('view.xsl'); $xsl = new XSLTProcessor(); $xsl->importStyleSheet($view); echo $xsl->transformToXML($data); ?> 

Source: https://habr.com/ru/post/141673/


All Articles