индекс в цикле XSL

У меня есть два вложенных цикла в XSL, в данный момент я использую position(), но это не то, что мне нужно.

<xsl:for-each select="abc">
  <xsl:for-each select="def">
   I wanna my variable in here increasing fluently 1,2,3,4,5.....n
not like 1,2,3,1,2,3
  </xsl:for-each>
</xsl:for-each>

Можете ли вы дать мне какую-нибудь идею для этой заглушки. Большое спасибо!


person gacon    schedule 30.05.2009    source источник


Ответы (4)


С XSL проблема в том, что вы не можете изменить переменную (это больше похоже на константу, которую вы устанавливаете). Таким образом, увеличение переменной счетчика не работает.

Неуклюжим обходным путем для получения последовательного подсчета (1,2,3,4,...) будет вызов position() для получения итерации тега «abc» и еще один вызов position() для получения вложенного «def "Итерация тега. Затем вам нужно будет умножить итерацию «abc» на количество содержащихся в ней тегов «def». Вот почему это «неуклюжий» обходной путь.

Предполагая, что у вас есть два вложенных тега «def», XSL будет выглядеть следующим образом:

<xsl:for-each select="abc">
    <xsl:variable name="level1Count" select="position() - 1"/>
    <xsl:for-each select="def">
        <xsl:variable name="level2Count" select="$level1Count * 2 + position()"/>
        <xsl:value-of select="$level2Count" />
    </xsl:for-each>
</xsl:for-each>
person pythonquick    schedule 30.05.2009
comment
Большое спасибо, pythonquick, ваш код отлично работает для меня! Мне потребовалось много времени. Благодарю вас! - person gacon; 30.05.2009
comment
Обратите внимание, что это будет работать только в том случае, если каждый abc имеет одинаковое количество дочерних элементов. Кроме того, это работает только с жестко заданным счетчиком def. - person jelovirt; 01.06.2009
comment
Очень полезно! Я добавил дополнительный ответ, который работает для переменного количества детей def. - person Nate Cook; 12.09.2011
comment
У меня есть вопрос: stackoverflow.com/questions/26809765/. Не могли бы вы дать мне решение. Спасибо. - person Si8; 10.11.2014

Просто измените способ выбора элементов для цикла:

<xsl:for-each select="abc/def">
    <xsl:value-of select="position()"/>
</xsl:for-each>

Если вам особенно нужно сохранить вложенные циклы, рассмотрите возможность добавления еще одного цикла, подобного этому:

<xsl:variable name="items" select="//abc/def"/>
<xsl:for-each select="abc">
    <xsl:for-each select="def">
        <xsl:variable name="id" select="generate-id()"/>
        <xsl:for-each select="$items">
            <xsl:if test="generate-id()=$id">
                 <xsl:value-of select="position()"/>
            </xsl:if>
        </xsl:for-each>
    </xsl:for-each>
</xsl:for-each>
person mousio    schedule 05.04.2011

Это расширение ответа pythonquick, которое обрабатывает разное количество подэлементов:

<xsl:for-each select="abc">  
    <xsl:variable name="level1Position" select="position()"/>
    <xsl:variable name="priorCount" select="count(../abc[position() &lt; $level1Position]/def)"/>  
    <xsl:for-each select="def">
        <xsl:variable name="level2Count" select="$priorCount + position()"/>
        <xsl:value-of select="$level2Count" />
    </xsl:for-each>
</xsl:for-each>

Вход:

<root>
    <abc>
        <def>A</def>
        <def>B</def>
        <def>C</def>
    </abc>
    <abc>
        <def>D</def>
        <def>E</def>
    </abc>
    <abc>
        <def>F</def>
    </abc>
    <abc>
        <def>G</def>
        <def>H</def>
        <def>I</def>
    </abc>
</root>
person Nate Cook    schedule 11.09.2011

person    schedule
comment
это не создаст последовательность 1,2,3,4,..., если только под тегом abc нет только одного вложенного тега def. - person pythonquick; 30.05.2009
comment
Спасибо, Крис Доггетт, но моя проблема в том, что когда я использую position() во втором цикле внутри, он продолжается с rezo, а не по последнему индексу в первом цикле. Так что я не мог использовать ваше предложение! Но ваше предложение может быть полезно для меня в последнее время, еще раз спасибо, Крис! - person gacon; 30.05.2009