Ответ 1
Один не сохраняет итерации, которые произошли в xsl: for-each, потому что XSLT - это функциональный язык и переменные неизменяемы.
Следующее преобразование находит желаемый максимум:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:template match="/"> <xsl:call-template name="maximum"> <xsl:with-param name="pNodes" select="*/Question"/> </xsl:call-template> </xsl:template> <xsl:template name="maximum"> <xsl:param name="pNodes"/> <xsl:variable name="vNumNodes" select="count($pNodes)"/> <xsl:choose> <xsl:when test="$vNumNodes = 1"> <xsl:value-of select="count($pNodes[1]/Response)"/> </xsl:when> <xsl:otherwise> <xsl:variable name="vHalf" select="floor($vNumNodes div 2)"/> <xsl:variable name="vMax1"> <xsl:call-template name="maximum"> <xsl:with-param name="pNodes" select="$pNodes[not(position() > $vHalf)]"/> </xsl:call-template> </xsl:variable> <xsl:variable name="vMax2"> <xsl:call-template name="maximum"> <xsl:with-param name="pNodes" select="$pNodes[position() > $vHalf]"/> </xsl:call-template> </xsl:variable> <xsl:value-of select= "$vMax1*($vMax1 >= $vMax2) + $vMax2*($vMax2 > $vMax1)"/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
При применении к предоставленному XML-документу:
<Survey> <Question> <Response text="Website" /> <Response text="Print Ad" /> </Question> <Question> <Response text="Yes" /> </Question> </Survey>
получается желаемый результат:
2
Обратите внимание на следующее: шаблон с именем "maximum
" вызывает себя рекурсивно и реализует DVC ( Divide and Conquer), чтобы минимизировать глубину стека рекурсии. Список узлов разбивается на два, максимальные значения двух списков вычисляются (рекурсивно) и возвращается больше из них.