1

I need to declare an array in my xslt template like say (pseudo code) myarray = [] //declaration of empty array Then i need to put some strings like below one at a time myarray = [doc] // put a string into the array Then i need to retrieve each element in the array and compare with another string like foreach myarray[i]{ tempstring = myarray[i] test=compare(somes-tring,tempstring) then do some action break else continue loop till all element in array are compared

` }`

Then if no string in array matches "some-string" then append some-string to the array.

After some steps of iteration is over empty myarray

5
  • 2
    Almost certainly an XY problem. XSLT doesn't have a notion of arrays and while it is probably possible to simulate these, as it is a Turing-complete language it would be extremely difficult and unintuitive as compared to any solution that uses the language the way it is designed to be used. I strongly recommend you rephrase your question to describe the actual problem you are trying to solve. Commented Oct 9, 2020 at 16:33
  • XSLT 3 with XPath 3.1 support has an array data type but it is not clear where/whether you need it. The only iteration in XSLT 3 is xsl:iterate, there you can pass on an array as an xsl: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. Commented Oct 9, 2020 at 16:52
  • Tell us what the input and output of your transformation are, and how they relate: don't tell us how you would tackle the problem in a different (procedural) programming language. Commented Oct 9, 2020 at 19:34
  • @Martin Honnen I stand corrected! Commented Oct 10, 2020 at 6:47
  • @ Martin Honnen Yes i need the same XSLT 3 with XPath 3.1 array implementation with put , get and emptying the array for reuse . My requirement is to use the array for string comparision to see whether a string already exist or not and if exist then do some action else continue to add the compared string to the array for string next comparision Commented Oct 13, 2020 at 6:23

1 Answer 1

1

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 &lt; $myOrd]"/>
            <item ord="{./*[@index = $index]/@ord}" index="{$index}"><xsl:value-of select="$value"/></item>
            <xsl:copy-of select="./*[@ord &gt; $myOrd]"/>
        </xsl:if>
        <xsl:if test="./*[@index = $index] and not($value)">
            <xsl:variable name="myOrd" select="./*[@index = $index]/@ord"/>
            <xsl:copy-of select="./*[@ord &lt; $myOrd]"/>
            <xsl:copy-of select="./*[@ord &gt; $myOrd]"/>
        </xsl:if>
        <xsl:if test="not(./*[@index = $index])">
            <xsl:variable name="maxOrd" select="number(./*[last()]/@ord + 1)"/>
            <xsl:copy-of select="./*[@ord &lt; $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 &gt;= 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 &gt;= 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 &gt;= 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 &gt;= 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 &gt;= 0]"/>
        </dump>

        <!-- end of the loop -->
    </xsl:template> 

    <xsl:template match="/" mode="dump">
        <xsl:message>Array:</xsl:message>
        <xsl:for-each select="*[@index &gt; -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>
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your elaborate response ..your stylesheet version is 1.0 Can we use version 3.0 with xpath array functionality specified below with put and get method of array in it? w3.org/TR/xpath-functions-31/#func-array-size Btw i could not resolve these statement in your post 'select="./*[@index = $index]/@ord"' Could you please tell how these statement executes?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.