如何在XSLT中显示字符n次?

如何在XSLT中显示字符n次?,xslt,Xslt,我有一个带参数的模板。如何插入制表符n次 n是参数的值。递归调用即可;输出一个选项卡,然后在传入n-1的情况下再次调用相同的模板(如果n>1) <xsl:template name="repeat"> <xsl:param name="output" /> <xsl:param name="count" /> <xsl:if test="$count &gt; 0"> <xsl:value-of select="$

我有一个带参数的模板。如何插入制表符n次


n是参数的值。

递归调用即可;输出一个选项卡,然后在传入n-1的情况下再次调用相同的模板(如果n>1)

<xsl:template name="repeat">
  <xsl:param name="output" />
  <xsl:param name="count" />
  <xsl:if test="$count &gt; 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>

正如已经指出的,这个示例实际上将输出至少一个。根据我的经验,如果输出是空白,通常需要它。您可以按照自己认为合适的任何方式调整递归模板的原理。

在XSLT 2.0中:

<xsl:for-each select="1 to $count">&#x9;</xsl:for-each>
(遗憾的是,我怀疑如果您使用的是XSLT2.0,就不需要问这个问题了)

XSLT 1.0中经常使用的另一种技术是hack:

<xsl:for-each select="//*[position() &lt;= $count]">&#x9;</xsl:for-each>

如果源文档中的元素数大于要输出的制表符数,则此选项有效。

全局定义足够长的制表符数组:

<xsl:variable name="TABS" select="'&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;'" />

然后像这样使用:

<xsl:value-of select="fn:substring($TABS, 1, fn:number($COUNT))" />
<xsl:value-of select="functx:repeat-string('&#x9;', n)" />

这对我来说似乎是最简单、最灵活的

对于XSLT1.0(或者可能是1.1)

10
	
当然,count变量是分配n参数的地方

我使用变量repeat来保存制表符,但是您可以将$repeat替换为序列元素中单引号中的制表符。注意:这个变量的长度可以大于1,这就产生了一系列的可能性

它不使用递归,因此不会遇到递归限制

我不知道可以用于计数的最大值,但我测试了10000个。

(XSLT 1.0)

用法示例:

<xsl:call-template name="tabs">
   <xsl:with-param name="n" select="3"/>
</xsl:call-template>

我发现了一个LGPL许可的库,名为functx,因为我确信一定有人已经完成了这项工作。。。这是一个“标准库”类型的XSLT库,其中包含一个名为repeat string的函数。从文档中:

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>&quot;</xsl:text>
                      <xsl:value-of select="@name" />
                      <xsl:text>&quot;: </xsl:text>
                      <xsl:text>&quot;</xsl:text>
                      <xsl:value-of select="$pusher.notifications.email.server" />
                      <xsl:text>&quot;\&#xA;</xsl:text>
                  </xsl:when>
                  ...
              </xsl:choose>
          </xsl:for-each>
      </xsl:template>
    </xsl:stylesheet>

....
...
"
": 
"
“\
;
...
因此,要将制表符打印n次,请如下所示:

<xsl:value-of select="fn:substring($TABS, 1, fn:number($COUNT))" />
<xsl:value-of select="functx:repeat-string('&#x9;', n)" />

我知道这个问题已经很老了,但我希望这个问题仍然能帮助一些人


+1用于固定的“如果使用此模式,您可能会下地狱”迭代。很多时候,样式表有足够的节点,所以
document(“”)//node()
很方便。@Alejandro我认为你应该对答案发表评论,或者如果你认为接受的答案太错误,就添加你自己的答案。您编辑了其他用户提供的内容,这只是为了提高可读性或添加信息。请注意,接受的答案是错误的。@Alejandro您可以要求澄清任何疑问。联合国阿布拉佐@贝里萨里乌斯:从我看来,编辑并不是不明智的(即使这真的是一个错误的答案。)@Flynn明白了。删除以前的评论。对不起。@Alejandro:啊,这更有道理;测试应为
1
,而不是0。你以前没有费心解释为什么它是错的。它应该至少输出一个,就像每当你想插入X空格时,在99%的情况下你必须至少插入一个,因此我的标题中的
“首先测试cero迭代。”@Alejandro:这只告诉我,即使输入为零,它也会输出一次,这并没有错。显然,这不是你的意思,但没有得到很好的解释