假设我有以下xml文件:
<root>
<header>
<headernodes1/>
<headernodes2/>
</header>
<items>
<itemno>1</itemno>
<itemtext>first item</itemtext>
<loop>
<range>
<rangefrom>4711</rangefrom>
<rangeto>4713</rangeto>
</range>
<content>content in the first loop</content>
</loop>
<loop>
<range>
<rangefrom>4715</rangefrom>
<rangeto>4718</rangeto>
</range>
<content>content in the second loop</content>
</loop>
</items>
<footernodes/>
</root>
<item>
之前的<loop>
中的页眉,页脚和节点应该被复制。
如果未显示<rangeto>
,则只需复制<loop>
段。否则,如果确实出现,则复制<loop>
段,如下例所示:
<loop>
<range>
<rangefrom>4711</rangefrom>
</range>
<content>content in the first loop</content>
</loop>
<loop>
<range>
<rangefrom>4712</rangefrom>
</range>
<content>content in the first loop</content>
</loop>
<loop>
<range>
<rangefrom>4713</rangefrom>
</range>
<content>content in the first loop</content>
</loop>
<loop>
<range>
<rangefrom>4715</rangefrom>
</range>
<content>content in the second loop</content>
</loop>
<loop>
<range>
<rangefrom>4716</rangefrom>
</range>
<content>content in the second loop</content>
</loop>
<loop>
<range>
<rangefrom>4717</rangefrom>
</range>
<content>content in the second loop</content>
</loop>
<loop>
<range>
<rangefrom>4718</rangefrom>
</range>
<content>content in the second loop</content>
</loop>
XSLT 1.0中是否有解决方案?
非常感谢你的帮助和帮助。咨询。
来自德国的问候, →
答案 0 :(得分:0)
XSLT没有循环,因为它没有可写变量(即不能有循环计数器)。
但它还有别的东西:递归!
<!-- process <loop> without <rangeto> directly as single item -->
<xsl:template match="loop[range/rangefrom and not(range/rangeto)]">
<xsl:apply-templates select="." mode="single" />
</xsl:template>
<!-- process <loop> with <rangefrom>/<rangeto> as a succession of single items -->
<xsl:template match="loop[range/rangefrom <= range/rangeto]">
<xsl:param name="i" select="range/rangefrom" />
<xsl:apply-templates select="." mode="single">
<xsl:with-param name="i" select="$i" />
</xsl:apply-templates>
<xsl:if test="$i < range/rangeto">
<!-- recursive step: same node, incremented index -->
<xsl:apply-templates select=".">
<xsl:with-param name="i" select="$i + 1" />
</xsl:apply-templates>
</xsl:if>
</xsl:template>
<!-- single item: outputs its index as <rangefrom> -->
<xsl:template match="loop" mode="single">
<xsl:param name="i" select="range/rangefrom" />
<xsl:copy>
<range>
<rangefrom><xsl:value-of select="$i" /></rangefrom>
</range>
<xsl:copy-of select="content" />
</xsl:copy>
</xsl:template>
现代XSLT引擎将此识别为尾递归并将其优化为迭代,因此您不会看到长循环的“递归太深”错误。
答案 1 :(得分:0)
试试以下
<xsl:template match="/root">
<good>
<header>
<xsl:apply-templates select="header"/>
</header>
<footernodes>
<xsl:apply-templates select="footernodes"/>
</footernodes>
<xsl:for-each select="items/loop">
<xsl:if test="range/rangeto!=''">
<xsl:call-template name="range">
<xsl:with-param name="rangedata" select="range"/>
<xsl:with-param name="contentdata" select="content"/>
<xsl:with-param name="vardata" select="range/rangefrom"/>
</xsl:call-template>
</xsl:if>
</xsl:for-each>
</good>
</xsl:template>
<xsl:template match="header">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="footernodes">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template name="range">
<xsl:param name="rangedata"/>
<xsl:param name="contentdata"/>
<xsl:param name="vardata"/>
<xsl:if test="$vardata <=$rangedata/rangeto">
<loop>
<range>
<rangefrom>
<xsl:value-of select="$vardata"/>
</rangefrom>
<content>
<xsl:value-of select="$contentdata"/>
</content>
</range>
</loop>
<xsl:call-template name="range">
<xsl:with-param name="rangedata" select="$rangedata"/>
<xsl:with-param name="contentdata" select="$contentdata"/>
<xsl:with-param name="vardata" select="$vardata+1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
你可以使用递归来实现你想要的东西