javaxmlxsltcollectionsxalan

Work with java collections in XSL using xalan extension


I want to iterate ArrayList <String> and put all strings to output tree, but have no any idea how to do it.

java method:

public ArrayList<String> getErrorList(String name) {
    if (errorMap.containsKey(name)) {
        return errorMap.get(name);
    }
    return new ArrayList<>();
}

xsl document:

<xsl:variable name="list">
    <xsl:value-of select="validator:getErrorList($validator, 'model')"/>
</xsl:variable>

<tr>
    <td style="color: red;">
        <ul>
            <li> first string from ArrayList </li>
            . . .
            <li> last string from ArrayList </li>
        </ul>
    </td>
</tr>

Solution

  • Your mistake was to initialize variable such as

    <xsl:variable name="list">
        <xsl:value-of select="validator:getErrorList($validator, 'model')"/>
    </xsl:variable>
    

    because xslt thinks, that value of this variable is #STRING, so you'll got error

    For extension function, could not find method java.util.ArrayList.size([ExpressionContext,] #STRING).

    You have to use next declaration, instead of previous:

    <xsl:variable name="list" select="validator:getErrorList($validator, 'model')"/>
    

    so, method getErrorList would return ArrayList object. Next code will show you how to iterate ArrayList collection, using XSL functional:

    <xsl:variable name="list" select="validator:getErrorList($validator, 'model')"/>
    <xsl:variable name="length" select="list:size($list)"/>
    <xsl:if test="$length > 0">
        <xsl:call-template name="looper">
            <xsl:with-param name="iterations" select="$length - 1"/>
            <xsl:with-param name="list" select="$list"/>
        </xsl:call-template>
    </xsl:if>
    . . .
    <xsl:template name="looper">
        <xsl:param name="iterations"/>
        <xsl:param name="list"/>
        <xsl:if test="$iterations > -1">
            <xsl:value-of select="list:get($list, $iterations)"></xsl:value-of>
            <xsl:call-template name="looper">
                 <xsl:with-param name="iterations" select="$iterations - 1"/>
                   <xsl:with-param name="list" select="$list"/>
              </xsl:call-template>
         </xsl:if>
    </xsl:template>
    

    So, you have to use recursion, 'cause it's not possible to use loops in functional language, such as XSLT. You can read about it here