正如 Michael Kay 所说,XSLT 2.0 将成为您的朋友,因为它可以轻松处理序列。事实上,你甚至不需要递归模板,因为你可以使用方便的 tokenize 函数来分割你的字符串
<xsl:variable name="fields" select="tokenize($input, ',')" />
然后,例如,要获得第二个字段,您可以这样做
<xsl:value-of select="$fields[2]"/>
但是,如果您坚持使用 XSLT 1.0,您将需要做一些额外的工作。目前,您的递归模板所做的只是输出一系列字符。这些构成了结果树的一部分,因此 XSLT 最初无法访问它们。不过,此时您需要做的是输出元素。
<xsl:variable name="v" select="substring-before($input, ',')"/>
<field>
<xsl:value-of select="$v"/>
</field>
接下来,您需要将现有的xsl:call-template包装在一个变量中,这样您就可以开始访问模板调用的结果。
<xsl:variable name="fields">
<xsl:call-template name="SimpleStringLoop">
<xsl:with-param name="input" select="'1,2,3,4,'"/>
</xsl:call-template>
</xsl:variable>
现在,fields变量此时包含一个“结果树片段”,但您希望能够访问其中的节点。这就是扩展函数的用武之地。有一个扩展可以将结果树片段转换为节点集,因此您可以在其上使用 XSLT 函数。这在很大程度上取决于您使用的命名空间的处理器,但最终它将允许您编写如下内容:
<xsl:value-of select="msxml:node-set($fields)/field[2]"/>
试试这个 XSLT 作为示例。注意,我在这里使用的是 Mircosoft 的 XSLT 处理器。其他 XSLT 处理器可用....
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxml="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxml">
<xsl:template match="/*">
<xsl:variable name="fields">
<xsl:call-template name="SimpleStringLoop">
<xsl:with-param name="input" select="'1,2,3,4,'"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="msxml:node-set($fields)/field[2]"/>
</xsl:template>
<xsl:template name="SimpleStringLoop">
<xsl:param name="input"/>
<xsl:if test="string-length($input) > 0">
<xsl:variable name="v" select="substring-before($input, ',')"/>
<field>
<xsl:value-of select="$v"/>
</field>
<xsl:call-template name="SimpleStringLoop">
<xsl:with-param name="input" select="substring-after($input, ',')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
有关节点集的更多信息,请尝试此链接作为开始:
http://www.xml.com/pub/a/2003/07/16/nodeset.html