Можно ли вести подсчет в цикле for-each в xslt? - PullRequest
1 голос
/ 17 сентября 2010

Мне нужно вести подсчет элементов, которые соответствуют условию при циклическом просмотре списка узлов, используя for-each.

Я использовал position (), но это неверно, так как мне нужно продолжать работуИтого.

Любая помощь будет очень признательна.

Ответы [ 3 ]

2 голосов
/ 17 сентября 2010

Я думаю, вам придется переписать цикл в рекурсию. Затем вы можете передать все виды переменных в следующую итерацию в качестве аргументов.

1 голос
/ 17 сентября 2010

Мне нужно вести подсчет предметов, которые соответствовать условию во время цикла через список узлов, используя for-each.

Я использовал position (), но это неправильно, так как мне нужно продолжать работать общий.

Любая помощь будет очень признательна.

В XSLT это обычно можно сделать с помощью рекурсии.

FXSL предлагает простой способ создания снимка шагов вычисления.

Используйте scanl или scanl1 шаблон / функцию FXSL

В XSLT 1.0 это преобразование:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
xmlns:myAdd="f:myAdd"
xmlns:myParam="f:myParam"
>
  <xsl:import href="scanl.xsl"/>
  <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <!-- To be applied on: numList.xml -->
  <myAdd:myAdd/>

  <myParam:myParam>0</myParam:myParam>

  <xsl:template match="/">
    <xsl:variable name="vFun" select="document('')/*/myAdd:*[1]"/>
    <xsl:variable name="vZero" select="document('')/*/myParam:*[1]"/>


    <xsl:call-template name="scanl">
      <xsl:with-param name="pFun" select="$vFun"/>
      <xsl:with-param name="pQ0" select="$vZero" />
      <xsl:with-param name="pList" select="/*/num"/>
    </xsl:call-template>

    - - - - - - - - - - -

     <xsl:call-template name="scanl1">
      <xsl:with-param name="pFun" select="$vFun"/>
      <xsl:with-param name="pList" select="/*/num"/>
    </xsl:call-template>
  </xsl:template>

  <xsl:template match="myAdd:*" mode="f:FXSL">
    <xsl:param name="pArg1" select="0"/>
    <xsl:param name="pArg2" select="0"/>

    <xsl:value-of select="$pArg1 + $pArg2"/>
  </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>

производит промежуточные суммы (промежуточные результаты вычисления sum()):

<el>0</el>
<el>1</el>
<el>3</el>
<el>6</el>
<el>10</el>
<el>15</el>
<el>21</el>
<el>28</el>
<el>36</el>
<el>45</el>
<el>55</el>

    - - - - - - - - - - -

<el>01</el>
<el>3</el>
<el>6</el>
<el>10</el>
<el>15</el>
<el>21</el>
<el>28</el>
<el>36</el>
<el>45</el>
<el>55</el>

Соответствующее преобразование XSLT 2.0, дающее тот же результат, это :

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
exclude-result-prefixes="f">
  <xsl:import href="../f/func-scanl.xsl"/>
  <xsl:import href="../f/func-Operators.xsl"/>

  <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <xsl:template match="/">
    <xsl:value-of separator=", " select="f:scanl(f:add(), 0, /*/*)"/>
     <xsl:text>&#xA;- - - - - - - - - - -&#xA;</xsl:text>
     <xsl:value-of separator=", "  select="f:scanl1(f:add(), /*/*)"/>
  </xsl:template>
</xsl:stylesheet>

Вы можете передать в качестве параметра f:scanl() любую функцию с двумя аргументами, первый из которых является текущим накопленным результатом, а второй - текущим элементом последовательности, переданным в f:scanl() в качестве последнего аргумента. Второй аргумент f:scanl() является начальным значением аккумулятора. Как правило, это будет 0 для суммирования и 1 для вычисления продукта.

f:scanl1() почти совпадает с f:scan(), но требует, чтобы аргумент последовательности был не пустым, и использует свой первый элемент в качестве начального значения аккумулятора.

1 голос
/ 17 сентября 2010

Две альтернативы. С этим входом:

<root>
    <number>1</number>
    <number>2</number>
    <number>3</number>
    <number>4</number>
    <number>5</number>
</root>

Это таблицы стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="root">
        <result>
            <xsl:apply-templates/>
        </result>
    </xsl:template>
    <xsl:template match="number">
        <sum>
            <xsl:value-of select="sum(.|preceding-sibling::number)"/>
        </sum>
    </xsl:template>
</xsl:stylesheet>

И

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="root">
        <result>
            <xsl:apply-templates select="*[1]"/>
        </result>
    </xsl:template>
    <xsl:template match="number">
        <xsl:param name="pCount" select="0"/>
        <sum>
            <xsl:value-of select="$pCount + ."/>
        </sum>
        <xsl:apply-templates select="following-sibling::*[1]">
            <xsl:with-param name="pCount" select="$pCount + ."/>
        </xsl:apply-templates>
    </xsl:template>
</xsl:stylesheet>

Выход:

<result>
    <sum>1</sum>
    <sum>3</sum>
    <sum>6</sum>
    <sum>10</sum>
    <sum>15</sum>
</result>

Примечание : первый с «предыдущей» осью. Второй проходной параметр в узле при обработке узла.

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