我需要使用for-each循环遍历节点列表时保留与条件匹配的项目数。
我正在使用position(),但这是不正确的,因为我需要保持一个运行总计。
任何帮助都会非常感激。
答案 0 :(得分:2)
我认为你必须将循环重写为递归。然后你可以将各种变量作为参数传递给下一个迭代。
答案 1 :(得分:1)
两种选择。有了这个输入:
<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>
注意:第一个带有'前置'轴。第二个通过节点处理在节点中传递param。
答案 2 :(得分:1)
我需要保留一些项目 循环时匹配条件 通过使用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>
应用于此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>
- - - - - - - - - - -
</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()
几乎相同,但它要求其sequence参数为非空,并使用其第一项作为初始累加器值。