You can declare a dynamic array like this:
<xsl:variable name="myarray">
<item ord="-1" index="-1"/>
</xsl:variable>
Code with some tests (i assume you've already learned how to program loops in XSLT so i don't get into more detail here):
Code
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="myarray">
<item ord="-1" index="-1"/>
</xsl:variable>
<xsl:template match="/">
<xsl:param name="index"/>
<xsl:param name="value"/>
<xsl:if test="./*[@index = $index] and $value">
<xsl:variable name="myOrd" select="./*[@index = $index]/@ord"/>
<xsl:copy-of select="./*[@ord < $myOrd]"/>
<item ord="{./*[@index = $index]/@ord}" index="{$index}"><xsl:value-of select="$value"/></item>
<xsl:copy-of select="./*[@ord > $myOrd]"/>
</xsl:if>
<xsl:if test="./*[@index = $index] and not($value)">
<xsl:variable name="myOrd" select="./*[@index = $index]/@ord"/>
<xsl:copy-of select="./*[@ord < $myOrd]"/>
<xsl:copy-of select="./*[@ord > $myOrd]"/>
</xsl:if>
<xsl:if test="not(./*[@index = $index])">
<xsl:variable name="maxOrd" select="number(./*[last()]/@ord + 1)"/>
<xsl:copy-of select="./*[@ord < $maxOrd]"/>
<item ord="{$maxOrd}" index="{$index}"><xsl:value-of select="$value"/></item>
</xsl:if>
</xsl:template>
<xsl:template name="test">
<!-- start of the loop -->
<!-- iteration step 1 -->
<xsl:variable name="myarray">
<xsl:apply-templates select="$myarray">
<xsl:with-param name="index" select="3"/>
<xsl:with-param name="value" select="'value at 3'"/>
</xsl:apply-templates>
</xsl:variable>
<xsl:apply-templates select="$myarray" mode="dump"/>
<dump step="1">
<xsl:copy-of select="$myarray/*[@ord >= 0]"/>
</dump>
<!-- iteration step 2 -->
<xsl:variable name="myarray">
<xsl:apply-templates select="$myarray">
<xsl:with-param name="index" select="15"/>
<xsl:with-param name="value" select="'value at 15'"/>
</xsl:apply-templates>
</xsl:variable>
<xsl:apply-templates select="$myarray" mode="dump"/>
<dump step="2">
<xsl:copy-of select="$myarray/*[@ord >= 0]"/>
</dump>
<!-- iteration step 3 -->
<xsl:variable name="myarray">
<xsl:apply-templates select="$myarray">
<xsl:with-param name="index" select="5"/>
<xsl:with-param name="value" select="'value at 5'"/>
</xsl:apply-templates>
</xsl:variable>
<xsl:apply-templates select="$myarray" mode="dump"/>
<dump step="3">
<xsl:copy-of select="$myarray/*[@ord >= 0]"/>
</dump>
<!-- iteration step 4 -->
<xsl:variable name="myarray">
<xsl:apply-templates select="$myarray">
<xsl:with-param name="index" select="5"/>
<xsl:with-param name="value" select="'newValue at 5'"/>
</xsl:apply-templates>
</xsl:variable>
<xsl:apply-templates select="$myarray" mode="dump"/>
<dump step="4">
<xsl:copy-of select="$myarray/*[@ord >= 0]"/>
</dump>
<!-- iteration step 5 -->
<xsl:variable name="myarray">
<xsl:apply-templates select="$myarray">
<xsl:with-param name="index" select="15"/>
<xsl:with-param name="value" select="''"/>
</xsl:apply-templates>
</xsl:variable>
<xsl:apply-templates select="$myarray" mode="dump"/>
<dump step="5">
<xsl:copy-of select="$myarray/*[@ord >= 0]"/>
</dump>
<!-- end of the loop -->
</xsl:template>
<xsl:template match="/" mode="dump">
<xsl:message>Array:</xsl:message>
<xsl:for-each select="*[@index > -1]">
<xsl:sort select="@index" data-type="number"/>
<xsl:message>
<xsl:value-of select="concat('array[',@index,'] = ',.)"/>
</xsl:message>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Comment
- step 1: set value at index 3
- step 2: set value at index 15
- step 3: set value at index 5
- step 4: set value at index 5 (new value)
- step 5: remove value at index 15
Console Output
Array:
array[3] = value at 3
Array:
array[3] = value at 3
array[15] = value at 15
Array:
array[3] = value at 3
array[5] = value at 5
array[15] = value at 15
Array:
array[3] = value at 3
array[5] = newValue at 5
array[15] = value at 15
Array:
array[3] = value at 3
array[5] = newValue at 5
XML Output
<?xml version="1.0" encoding="UTF-8"?>
<dump step="1">
<item ord="0" index="3">value at 3</item>
</dump>
<dump step="2">
<item ord="0" index="3">value at 3</item>
<item ord="1" index="15">value at 15</item>
</dump>
<dump step="3">
<item ord="0" index="3">value at 3</item>
<item ord="1" index="15">value at 15</item>
<item ord="2" index="5">value at 5</item>
</dump>
<dump step="4">
<item ord="0" index="3">value at 3</item>
<item ord="1" index="15">value at 15</item>
<item ord="2" index="5">newValue at 5</item>
</dump>
<dump step="5">
<item ord="0" index="3">value at 3</item>
<item ord="2" index="5">newValue at 5</item>
</dump>
xsl:iterate, there you can pass on an array as anxsl:param, but always considering that it is any operation will just return a new array. XSLT 3 also has accumulators that might help storing and changing a value during processing of the document tree.