Область действия переменной xslt и ее использование - PullRequest
7 голосов
/ 12 февраля 2012

Я изучаю xslt и у меня был один вопрос о том, как я могу использовать переменную xslt в diff.для каждой петли.Я знаю, что xslt не является процедурным языком, поэтому переменная, объявленная в цикле for, не может быть доступна в другом цикле.Но есть ли способ, которым я могу просто объявить глобальную переменную, а затем присвоить какое-то значение в первом для цикла и использовать эту переменную во втором для цикла?

Любые идеи будут высоко оценены.*

Ответы [ 3 ]

14 голосов
/ 13 февраля 2012

есть ли способ, как я могу просто объявить глобальную переменную, а затем назначить некоторые значение в первом для цикла и использовать эту переменную во втором для цикла?

Способ присвоения значения 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
0 голосов
/ 13 февраля 2012
  1. Вы написали: ' XSL - это процедурный язык ' .. Ну, это не так. Это декларативный язык ..
  2. Переменная присваивается вместе с ее объявлением, переменные не меняются!
  3. Обычно мы следуем рекурсивному вызову для шаблонов, используя call-template, передавая им параметры .. ( это работает как рекурсивный вызов функции с передачей аргументов в процедурных языках )
    Это один из методов обработки счетчиков, условных циклов и т. д.

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

0 голосов
/ 12 февраля 2012

xsl:for-each не является циклом в том смысле, что в процедурных языках существуют циклы for или foreach, поэтому любой вопрос, говорящий о циклах, труден для понимания и труднее ответить.

Если вы хотитечтобы использовать глобальные переменные в XSLT, вы можете сделать это, но вы бы привязали значение к переменной, в которой вы его объявили (то есть глобально), вы не можете присвоить значение позже в for-each, как вы, кажется, хотите это сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...