область переменных 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>&#xA;</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' .. Ну, это не так. Это Декларативный Язык ..
  1. переменная назначается вместе с ее объявлением, переменные не меняются!
  2. обычно мы следуем рекурсивному вызову шаблонов, используя call-template передача им парамов .. (это работает как вызов рекурсивной функции с передачей аргументов на процедурных языках)
    это один из методов обработки графов и условные циклы и т. д..

мы будем рады помочь вам, если вы упомянете точный сценарий с образцом XML и вывод, который вы ожидаете от него:)