用xslt循环xml同一节点的不同子节点
遇到类似以下xml文件时,需要将每年的不同月份分别置于年的节点下,如果用C#的程序语言很容易实现,因为对xslt用的不多,这个还费了我一点心思。
<rows>
<row year="2004" month="2"/>
<row year="2004" month="5"/>
<row year="2005" month="2"/>
<row year="2004" month="7"/>
<row year="2005" month="4"/>
<row year="2005" month="8"/>
</rows>
最初构思还是定义一个变量用来记录循环,可是对变量的赋值却总是不能执行。浪费了我一个多小时,做完后发现原来非常简单,根本没有其他程序语言的实现那么复杂。写出来方便有需要的朋友使用。<row year="2004" month="2"/>
<row year="2004" month="5"/>
<row year="2005" month="2"/>
<row year="2004" month="7"/>
<row year="2005" month="4"/>
<row year="2005" month="8"/>
</rows>
<xsl:template match="row" mode="Month">
<Month Name="{@month}" ImageIndex="28" Link=""/>
</xsl:template>
<xsl:template match="row">
<xsl:variable name="pos" select="position() - 1" />
<xsl:if test="$pos = 0 or ../row[$pos]/@year != @year">
<Year Name="{@year}" ImageIndex="26">
<xsl:apply-templates select="../row[@year = current()/@year]" mode="Month" />
</Year>
</xsl:if>
</xsl:template>
<Month Name="{@month}" ImageIndex="28" Link=""/>
</xsl:template>
<xsl:template match="row">
<xsl:variable name="pos" select="position() - 1" />
<xsl:if test="$pos = 0 or ../row[$pos]/@year != @year">
<Year Name="{@year}" ImageIndex="26">
<xsl:apply-templates select="../row[@year = current()/@year]" mode="Month" />
</Year>
</xsl:if>
</xsl:template>