Since I need to apply the conversion in temporary variables, using xsl:key would not help. And if I need to use a Dimitre solution , I had to modify the existing code.
And, obviously, this was my mistake, about which I did not talk very much about this issue.
From the link in //programlisting[contains(.,'xsl:template name="process-level"')] provided by Dr. Kay I came to the conclusion that maybe someone else can use it later:
Style sheet
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs"> <xsl:output indent="yes"/> <xsl:template match="/*"> <rs> <xsl:call-template name="process-level"> <xsl:with-param name="context" select="r"/> <xsl:with-param name="level" select="0"/> </xsl:call-template> </rs> </xsl:template> <xsl:template name="process-level"> <xsl:param name="context" required="yes" as="element()*"/> <xsl:param name="level" as="xs:double"/> <xsl:for-each-group select="$context" group-starting-with="*[number(@lev) eq $level]"> <xsl:element name="{name()}"> <xsl:copy-of select="@id"/> <xsl:call-template name="process-level"> <xsl:with-param name="context" select="current-group()[position() != 1]"/> <xsl:with-param name="level" select="$level + 1"/> </xsl:call-template> </xsl:element> </xsl:for-each-group> </xsl:template> </xsl:stylesheet>
XML input
<rs> <r id="r1" lev="0"/> <r id="r2" lev="1"/> <r id="r3" lev="0"/> <r id="r4" lev="1"/> <r id="r5" lev="2"/> <r id="r6" lev="3"/> <r id="r7" lev="0"/> <r id="r8" lev="1"/> <r id="r9" lev="2"/> </rs>
And the result
<rs> <r id="r1"> <r id="r2"/> </r> <r id="r3"> <r id="r4"> <r id="r5"> <r id="r6"/> </r> </r> </r> <r id="r7"> <r id="r8"> <r id="r9"/> </r> </r> </rs>
source share