область переменных xslt и ее использование
Я изучаю xslt и имел один вопрос о том, как я могу использовать переменную xslt в diff. цикл for each. Я знаю, что xslt не является процедурным языком, поэтому переменная, объявленная в цикле for, не может быть доступна в другом цикле. Но есть ли способ, которым я могу просто объявить глобальную переменную, а затем назначить некоторое значение в первом цикле for и использовать эту переменную во втором цикле for?
любые идеи будут высоко оценены.
спасибо
3 ответов
есть ли способ я могу просто объявить глобальную переменную, затем назначить значение в первом для цикла и использовать эту переменную во втором для цикла?
способ присвоить значение xsl:variable
(конечно, это только инициализация) в xsl:for-each
, должен включать xsl:for-each
в теле переменной.
вот пример:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<xsl:variable name="vMax">
<xsl:for-each select="num">
<xsl:sort data-type="number" order="descending"/>
<xsl:if test="position() = 1">
<xsl:value-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
Values close to the maximum:
<xsl:text/>
<xsl:for-each select="num">
<xsl:if test="not($vMax - . > 3) ">
<xsl:value-of select="."/>
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
когда это преобразование применяется на следующий XML-документ...
<nums>
<num>01</num>
<num>02</num>
<num>03</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>07</num>
<num>08</num>
<num>09</num>
<num>10</num>
</nums>
...он сначала определяет vMax
переменная, которая получает свое значение из xsl:for-each
содержится в его теле.
тут vMax
переменная используется во втором xsl:for-each
для вывода всех чисел, которые "близки" к так вычисленному максимуму.
производится нужный, правильный результат:
Values close to the maximum:
07
08
09
10
также возможно сымитировать "присваивать" переменную с различным значения с помощью рекурсивно называемого именованного шаблона и передайте" новое значение " в качестве параметра вызываемому шаблону.
вот пример, показывающий эту технику. Здесь мы вычисляем максимум значений, содержащихся в узлах набора узлов. Каждый раз, когда мы обращаемся к следующему узлу в наборе узлов, текущий максимум сравнивается с этим значением, и при необходимости новый максимум становится значением следующего узла. Затем мы вызываем тот же шаблон рекурсивно, передавая в качестве значения текущего максимума новый максимум:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<xsl:call-template name="max">
<xsl:with-param name="pList" select="*"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="max">
<xsl:param name="pMax" select="-99999999"/>
<xsl:param name="pList"/>
<xsl:choose>
<xsl:when test="$pList[1]">
<xsl:variable name="vnewMax" select=
"$pMax * ($pMax >= $pList[1])
+
$pList[1] * not($pMax >= $pList[1])
"/>
<xsl:call-template name="max">
<xsl:with-param name="pMax" select="$vnewMax"/>
<xsl:with-param name="pList" select="$pList[position() > 1]"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$pMax"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
когда это преобразование применяется к тому же XML-документу (выше), получается нужный, правильный результат:
10
xsl:for-each
не является циклом в смысле for
или foreach
циклы существуют в процедурных языках, поэтому любой вопрос, говорящий о циклах, трудно понять и сложнее ответить.
если вы хотите использовать глобальные переменные в XSLT, вы можете это сделать, но вы бы привязали значение к переменной, где вы ее объявляете (т. е. глобально), вы не можете назначить значение позже в for-each
как вы, кажется, хотите сделать.
- XSL является процедурным lang' .. Ну, это не так. Это Декларативный Язык ..
- переменная назначается вместе с ее объявлением, переменные не меняются!
- обычно мы следуем рекурсивному вызову шаблонов, используя
call-template
передача им парамов .. (это работает как вызов рекурсивной функции с передачей аргументов на процедурных языках)
это один из методов обработки графов и условные циклы и т. д..
мы будем рады помочь вам, если вы упомянете точный сценарий с образцом XML и вывод, который вы ожидаете от него:)