Работа с коллекциями Java в XSL с использованием расширения xalan
Я хочу повторить ArrayList <String>
и положить все строки в выходное дерево, но понятия не имею, как это сделать.
Java-метод:
public ArrayList<String> getErrorList(String name) {
if (errorMap.containsKey(name)) {
return errorMap.get(name);
}
return new ArrayList<>();
}
документ xsl:
<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>
Я довольно новичок в xsl, поэтому я прошу вас о помощи.
2 ответа
Ваша ошибка состояла в том, чтобы инициализировать переменную, такую как
<xsl:variable name="list">
<xsl:value-of select="validator:getErrorList($validator, 'model')"/>
</xsl:variable>
потому что xslt считает, что значение этой переменной #STRING
, так что вы получите ошибку
Для функции расширения не удалось найти метод java.util.ArrayList.size([ExpressionContext,] #STRING).
Вы должны использовать следующее объявление вместо предыдущего:
<xsl:variable name="list" select="validator:getErrorList($validator, 'model')"/>
Итак, метод getErrorList
вернется ArrayList
объект. Следующий код покажет вам, как перебирать коллекцию ArrayList, используя функционал XSL:
<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>
Итак, вы должны использовать рекурсию, потому что невозможно использовать циклы на функциональном языке, таком как XSLT. Вы можете прочитать об этом здесь
Вы должны определить пространство имен для вашей функции расширения Java в вашей таблице стилей. Должно выглядеть xmlns:yourchoice = "javapackage.classname
, Предполагая, что метод getErrorList находится в классе ErrorListClass, он может выглядеть так:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:validator="mypackage.ErrorListClass"
exclude-result-prefixes="filecounter" version="1.0">
И тогда вы называете это в вашем XSLT
<xsl:variable name="list">
<xsl:value-of select="validator:getErrorList($validator, 'model')"/>
</xsl:variable>
Надеюсь, это поможет.
С наилучшими пожеланиями, Питер