我有一个带参数的模板。如何插入标签字符n次?
n是参数的值。
答案 0 :(得分:12)
只需递归调用它;输出一个标签,然后在传入n-1的情况下再次调用相同的模板,如果n> 1。
<xsl:template name="repeat">
<xsl:param name="output" />
<xsl:param name="count" />
<xsl:if test="$count > 0">
<xsl:value-of select="$output" />
<xsl:call-template name="repeat">
<xsl:with-param name="output" select="$output" />
<xsl:with-param name="count" select="$count - 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
正如已经指出的那样,这个例子实际上会输出至少一个。根据我的经验,输出是空格,通常需要它。您可以以任何您认为合适的方式调整递归模板的原理。
答案 1 :(得分:11)
在XSLT 2.0中:
<xsl:for-each select="1 to $count">	</xsl:for-each>
(遗憾的是,我怀疑如果你使用的是XSLT 2.0,你就不需要问这个问题了。)
XSLT 1.0常用的另一种技术是黑客攻击:
<xsl:for-each select="//*[position() <= $count]">	</xsl:for-each>
如果源文档中的元素数量大于要输出的制表符数量,则可以正常工作。
答案 2 :(得分:2)
(XSLT 1.0)
<xsl:template name="tabs">
<xsl:param name="n"/>
<xsl:if test="$n > 0"> <!-- When n = 0, output nothing. -->
<xsl:call-template name="tabs"> <!-- Recursive call: call same template... -->
<xsl:with-param name="n" select="$n - 1"/> <!-- ... for writing n - 1 tabs. -->
</xsl:call-template>
<xsl:text>	</xsl:text> <!-- Add one tab character. -->
</xsl:if>
</xsl:template>
使用示例:
<xsl:call-template name="tabs">
<xsl:with-param name="n" select="3"/>
</xsl:call-template>
答案 3 :(得分:1)
全局定义足够长的标签数组:
<xsl:variable name="TABS" select="'								'" />
然后像这样使用:
<xsl:value-of select="fn:substring($TABS, 1, fn:number($COUNT))" />
答案 4 :(得分:1)
这对我来说似乎是最简单和最灵活的。
对于XSLT 1.0(或者可能是1.1)。
<xsl:variable name="count">10</xsl:variable>
<xsl:variable name="repeat"><xsl:text>	</xsl:text></xsl:variable>
<xsl:sequence select="string-join((for $i in 1 to $count return $repeat),'')"/>
当然,计数变量是指定 n 参数的位置。
我使用变量重复来保存标签字符,但您可以将 $ repeat 替换为单引号中的标签字符在序列元素中。 注意:此变量的长度可以大于1,这会产生一大堆可能性。
它不使用递归,因此它不会遇到递归限制。
我不知道你可以用于计数的最大值,但我测试了它达到10,000。
答案 5 :(得分:0)
我发现了一个名为functx的LGPL授权库,因为我确信有人必须已经这样做了......这是一个标准的库#34;类型XSLT库,其中包含一个名为repeat-string的函数。来自文档:
functx:repeat-string函数返回一个字符串,该字符串由连接在一起的$ stringToRepeat的给定数量的副本组成。
我在代码中使用它的地方:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:functx="http://www.functx.com">
<xsl:import href="../buildlib/functx-1.0.xsl"/>
<xsl:output omit-xml-declaration="yes" />
<xsl:variable name="INDENT" select="' '" />
....
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="data-pusher-properties">
<xsl:for-each select="property">
<xsl:choose>
...
<xsl:when test="boolean(@value = '${pusher.notifications.server}')">
<xsl:value-of select="functx:repeat-string($INDENT, @indent)" />
<xsl:text>"</xsl:text>
<xsl:value-of select="@name" />
<xsl:text>": </xsl:text>
<xsl:text>"</xsl:text>
<xsl:value-of select="$pusher.notifications.email.server" />
<xsl:text>"\
</xsl:text>
</xsl:when>
...
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
因此,对于打印制表符n次,请按以下方式调用:
<xsl:value-of select="functx:repeat-string('	', n)" />
我知道这个问题已经过时了,但我希望这仍然有助于某人。