我想在XML文档中重复以下几行,n在变量$ n
中设置<Cell ss:StyleID="s22">
<Data ss:Type="String">WSCEAllergens[i]</Data>
</Cell>
而不是像
那样编写笨拙的级联<Cell ss:StyleID="s22">
<Data ss:Type="String">WSCEAllergens[0]</Data>
</Cell>
<xsl:if test="$n > 1>
<Cell ss:StyleID="s22">
<Data ss:Type="String">WSCEAllergens[1]</Data>
</Cell>
<xsl:if test="$n > 2>
<Cell ss:StyleID="s22">
<Data ss:Type="String">WSCEAllergens[2]</Data>
</Cell>
.
.
.
</xsl:if>
</xsl:if>
我想用一个优雅的模板解决这个问题,但我不知道如何将XML和文本字符串迭代地粘合在一起得到这样的东西:
n = 3的
<Cell ss:StyleID="s22">
<Data ss:Type="String">WSCEAllergens[0]</Data>
</Cell>
<Cell ss:StyleID="s22">
<Data ss:Type="String">WSCEAllergens[1]</Data>
</Cell>
<Cell ss:StyleID="s22">
<Data ss:Type="String">WSCEAllergens[2]</Data>
</Cell>
我已使用此模板将Daniel的代码应用于我的XSLT
<xsl:template name="repeater">
<xsl:param name="string"/>
<xsl:param name="n"/>
<xsl:param name="count" select="0"/>
<xsl:value-of select="normalize-space(
concat(substring-before($string,'['),
'[',$count,']',
substring-after($string,']')))" disable-output-escaping="yes"/>
<xsl:if test="$n - 1 > $count">
<xsl:call-template name="copyXML">
<xsl:with-param name="count" select="$count+1"/>
<xsl:with-param name="string" select="$string"/>
<xsl:with-param name="n" select="$n"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
并通过以下电话
<xsl:call-template name="repeater">
<xsl:with-param name="n" select="$nAllergens"/>
<xsl:with-param name="string">
<![CDATA[
<Cell ss:StyleID="s22"><Data ss:Type="String">WSCEAllergens[i]</Data></Cell>
]]>
</xsl:with-param>
</xsl:call-template>
<Cell ss:StyleID="s22">
<Data ss:Type="String">WSCEAllergens[0]</Data>
</Cell>
<Cell ss:StyleID="s22">
<Data ss:Type="String">WSCEAllergens[1]</Data>
</Cell>
<Cell ss:StyleID="s22">
<Data ss:Type="String">WSCEAllergens[2]</Data>
</Cell>
那很好。 但是,如果我想得到什么
<Cell ss:StyleID="s22">
<Data ss:Type="String">WSCEAllergens[0]</Data>
</Cell>
<Cell ss:StyleID="s22">
<Data ss:Type="String">WSCEAllergens[0]</Data>
</Cell>
<Cell ss:StyleID="s22">
<Data ss:Type="String">WSCEAllergens[1]</Data>
</Cell>
<Cell ss:StyleID="s22">
<Data ss:Type="String">WSCEAllergens[1]</Data>
</Cell>
<Cell ss:StyleID="s22">
<Data ss:Type="String">WSCEAllergens[2]</Data>
</Cell>
<Cell ss:StyleID="s22">
<Data ss:Type="String">WSCEAllergens[2]</Data>
</Cell>
我有 a)在我的模板中添加了第二行 b)将concat-call改为 CONCAT(子 - 前($字符串, '['), '[',$计数, ']',子串之后($字符串, ']'), 子 - 前($字符串, '['), '[',$计数, ']',子串之后($串, ']'))
我只会得到两种方式 WSCEAllergens [0] WSCEAllergens [0] WSCEAllergens [1] WSCEAllergens [2]
答案 0 :(得分:1)
对于i = 0到n,模板应返回CDATA字符串n x 2次。
嗯,这是相当微不足道的:
<xsl:template name="repeat">
<xsl:param name="string"/>
<xsl:param name="n"/>
<xsl:param name="i" select="0"/>
<xsl:if test="2 * $n > $i">
<xsl:value-of select="substring-before($string,'[i]')" disable-output-escaping="yes"/>
<xsl:value-of select="concat('[', floor($i div 2), ']')"/>
<xsl:value-of select="substring-after($string,'[i]')" disable-output-escaping="yes"/>
<xsl:call-template name="repeat">
<xsl:with-param name="string" select="$string"/>
<xsl:with-param name="n" select="$n"/>
<xsl:with-param name="i" select="$i + 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
或者,如果您愿意:
<xsl:template name="repeat">
<xsl:param name="string"/>
<xsl:param name="n"/>
<xsl:param name="i" select="0"/>
<xsl:if test="$n > $i">
<xsl:variable name="output">
<xsl:value-of select="substring-before($string,'[i]')"/>
<xsl:value-of select="concat('[', $i, ']')"/>
<xsl:value-of select="substring-after($string,'[i]')"/>
</xsl:variable>
<xsl:value-of select="concat($output, $output)" disable-output-escaping="yes"/>
<xsl:call-template name="repeat">
<xsl:with-param name="string" select="$string"/>
<xsl:with-param name="n" select="$n"/>
<xsl:with-param name="i" select="$i + 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
答案 1 :(得分:0)
这是一个选项。在示例中,元素generate
将被字符串$n
替换。我正在使用DOE(disable-output-escaping
),因此字符串是输出中的实际XML。如果它应该是一个字符串,只需删除DOE属性。
XML输入
<doc>
<generate/>
</doc>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="n" select="3"/>
<xsl:param name="baseString">
<![CDATA[
<Cell ss:StyleID="s22"><Data ss:Type="String">WSCEAllergens[i]</Data></Cell>
]]>
</xsl:param>
<!--Identity transform-->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="generate">
<xsl:call-template name="copyXML">
<xsl:with-param name="string" select="$baseString"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="copyXML">
<xsl:param name="string"/>
<xsl:param name="count" select="0"/>
<xsl:value-of select="normalize-space(
concat(substring-before($string,'['),
'[',$count,']',
substring-after($string,']')))" disable-output-escaping="yes"/>
<xsl:if test="$n - 1 > $count">
<xsl:call-template name="copyXML">
<xsl:with-param name="count" select="$count+1"/>
<xsl:with-param name="string" select="$string"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
XML输出
(转换后格式化。由于normalize-space()
,实际输出将在一行上。)
<doc>
<Cell ss:StyleID="s22">
<Data ss:Type="String">WSCEAllergens[0]</Data>
</Cell>
<Cell ss:StyleID="s22">
<Data ss:Type="String">WSCEAllergens[1]</Data>
</Cell>
<Cell ss:StyleID="s22">
<Data ss:Type="String">WSCEAllergens[2]</Data>
</Cell>
</doc>
另请注意,名称空间前缀ss
应绑定到输出中的命名空间。