2010-07-27 59 views
24

我对xlst比较陌生,并且对是否有任何方式来存储值并稍后进行更改(例如,在循环中增加一个变量)感到困惑。在XSLT中增加一个值

我有点困惑,因为不能改变它的值后,它的设置对我来说没有意义,使它更多的是一个常数。

比如我想做的事情是这样的:

<xsl:variable name="i" select="0" /> 
<xsl:for-each select="data/posts/entry"> 
    <xsl:variable name="i" select="$i + 1" /> 
    <!-- DO SOMETHING --> 
</xsl:for-each> 

如果任何人都可以见识一下是否有这样做
感谢

+0

感谢Dimitre,我没有意识到变量可以在for-each循环中重用。我的问题实际上比我发布的例子复杂得多,我找到了一个使用递归的解决方案,但是我会用你的建议看看更优雅的解决方案 – DonutReply 2010-07-29 12:14:37

+1

@Oliver虽然递归是通用的,但是有一些方法可以用递归替换迭代。这样可以优化时间和空间 - xslt应用程序。 – 2010-07-29 12:40:19

回答

28

XSLT是一种功能性的语言和除其他事项外,这意味着变量在XSLT是不可变的和onc e他们已经确定他们的价值不能改变。

下面是同样的效果可以在XSLT来实现:

<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="/"> 
    <posts> 
    <xsl:for-each select="data/posts/entry"> 
     <xsl:variable name="i" select="position()" /> 
     <xsl:copy> 
     <xsl:value-of select="concat('$i = ', $i)"/> 
     </xsl:copy> 
    </xsl:for-each> 
    </posts> 
</xsl:template> 
</xsl:stylesheet> 

当这种转变是在下面的XML文档应用:

<data> 
<posts> 
    <entry/> 
    <entry/> 
    <entry/> 
    <entry/> 
    <entry/> 
</posts> 
</data> 

结果是

<posts> 
    <entry>$i = 1</entry> 
    <entry>$i = 2</entry> 
    <entry>$i = 3</entry> 
    <entry>$i = 4</entry> 
    <entry>$i = 5</entry> 
</posts> 
1

我遇到了我自己两年替代方法前。你需要为此使用递归。我忘了确切的语法,但这个网站可能会有所帮助:

Tip: Loop with recursion in XSLT

战略工作基本如下:使用模板“方法”替换for循环。有没有收到参数i。在模板方法中执行for循环的正文。如果i > 0i - 1作为参数再次调用模板方法(递归)。

伪代码:

for i = 0 to 10: 
    print i 

变为:

def printer(i): 
    print i 
    if i < 10: 
     printer(i + 1) 
printer(0) 

请注意,在xsl:for-each使用position()(见其他答案),可以更简单,如果你想要做的是有一个变量增量。如果您想要更复杂的循环/条件,请使用此处说明的那种递归。

5

可以使用position()功能:

<xsl:for-each select="data/posts/entry"> 
    <xsl:text> 
    Postion: ' 
    </xsl:text> 
    <xsl:value-of select = "position()" /> 
    <xsl:text> 
    ' 
    </xsl:text> 
    <!-- DO SOMETHING --> 
</xsl:for-each>