.net 是否可以在xslt中为每个循环保留一个计数

.net 是否可以在xslt中为每个循环保留一个计数,.net,xslt,.net,Xslt,在使用for each循环遍历节点列表时,我需要保留与某个条件匹配的项的计数 我使用的是position(),但这是不正确的,因为我需要保持一个运行总数 任何帮助都将不胜感激 我认为您必须将循环重写为递归。然后,您可以将各种变量作为参数传递到下一次迭代中。我认为您必须将循环重写为递归。然后,您可以将各种变量作为参数传递到下一次迭代中。有两种选择。通过此输入: <root> <number>1</number> <number>2&l

在使用for each循环遍历节点列表时,我需要保留与某个条件匹配的项的计数

我使用的是position(),但这是不正确的,因为我需要保持一个运行总数


任何帮助都将不胜感激

我认为您必须将循环重写为递归。然后,您可以将各种变量作为参数传递到下一次迭代中。

我认为您必须将循环重写为递归。然后,您可以将各种变量作为参数传递到下一次迭代中。

有两种选择。通过此输入:

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

1.
2.
3.
4.
5.
此样式表:

<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>


输出:

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

1.
3.
6.
10
15

注意:第一个轴为“前一个”。第二种方法是逐节点处理传递参数。

两种方法。通过此输入:

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

1.
2.
3.
4.
5.
此样式表:

<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>


输出:

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

1.
3.
6.
10
15
注意:第一个轴为“前一个”。第二个是在逐节点处理中传递参数

我需要清点那些 循环时匹配条件 通过使用for each的节点列表

我使用的是position(),但这是 不正确,因为我需要保持跑步 总数

任何帮助都将不胜感激

在XSLT中,这通常可以使用递归来完成

FXSL提供了一种生成计算步骤快照的简单方法

使用FXSL的
scanl
scanl1
模板/功能

在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>
产生相同结果的相应XSLT 2.0转换如下所示:

<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>
<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()
的第二个参数是初始累加器值。通常,求和时为
0
,计算乘积时为
1

f:scanl1()
f:scan()
几乎相同,但它要求其序列参数为非空,并使用其第一项作为初始累加器值

我需要清点那些 循环时匹配条件 通过使用for each的节点列表

我使用的是position(),但这是 不正确,因为我需要保持跑步 总数

任何帮助都将不胜感激

在XSLT中,这通常可以使用递归来完成

FXSL提供了一种生成计算步骤快照的简单方法

使用FXSL的
scanl
scanl1
模板/功能

在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>
产生相同结果的相应XSLT 2.0转换如下所示:

<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>
<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()
的第二个参数是初始累加器值。通常,求和时为
0
,计算乘积时为
1


f:scanl1()
f:scan()
几乎相同,但它要求其序列参数为非空,并使用其第一项作为初始累加器值

您可以发布一个XML、XSL和所需输出的示例吗?对每个使用
的倾向对于具有过程编程背景的人来说是典型的,这也是为什么许多程序员在XSLT方面遇到问题、感到沮丧并放弃的原因。函数式编程技术是一种不同的工作方式,但更符合XSLT。学习如何利用递归、模板匹配和“推送”样式将使您的XSLT开发更加容易。谢谢Mads,您有什么好的资源或书籍可以向我介绍吗?好问题(+1)。请参阅我的答案,了解一个通用且功能强大的解决方案,该解决方案也可用于一大类类似问题。:)您可以发布一个XML、XSL和所需输出的示例吗?对每个
使用
的倾向对于具有过程编程背景的人来说是典型的,这也是为什么许多程序员在XSLT方面遇到问题、感到沮丧并放弃的原因。函数式编程技术是一种不同的工作方式,但更符合XSLT。学习如何利用递归、模板匹配和“推送”样式将使您的XSLT开发更加容易。谢谢Mads,您有什么好的资源或书籍可以向我介绍吗?好问题(+1)。请参阅我的答案,了解一个通用且功能强大的解决方案,该解决方案也可用于一大类类似问题。:)+1@tdammers-提供一个使用递归和
调用模板
的简短示例会很有帮助,这样@Burt就可以理解如何使用它。+1@tdammers-提供一个使用递归和
调用模板的简短示例会很有帮助