我将逗号分隔的字符串拆分如下:
<xsl:call-template name="SimpleStringLoop">
<xsl:with-param name="input" select="'1,2,3,4,'"/>
</xsl:call-template>
<xsl:template name="SimpleStringLoop">
<xsl:param name="input"/>
<xsl:if test="string-length($input) > 0">
<xsl:variable name="v" select="substring-before($input, ',')"/>
<xsl:value-of select="$v"/>
<xsl:call-template name="SimpleStringLoop">
<xsl:with-param name="input" select="substring-after($input, ',')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
如何在数组中访问所有提取的值? 我需要访问它们中的每一个并在xslt过滤中使用它们。 调用SimpleStringLoop时,$ v第一次保持值1,另一次保持2,依此类推。但有没有办法利用$ v就像在$ v [1],$ v [2]
等数组中使用索引一样所以我有$v[1]=1, $v[2] =2 etc..
或者我是如此愚蠢,以至于我根本不理解这个递归过程?
答案 0 :(得分:3)
正如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>
目前,字段变量此时包含“结果树片段”,但您希望能够访问其中的节点。这是扩展函数的用武之地。有一个扩展可以将结果树片段转换为节点集,因此您可以在其上使用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>
有关节点集的更多信息,请尝试以此链接作为开头:
答案 1 :(得分:2)
您需要XSLT 2.0。在XSLT 1.0中,没有数据类型来处理字符串序列。您可以创建一个包含变量中字符串的节点集,如果您有exslt:node-set()扩展,那么您可以处理节点集,但它是一个糟糕的替代品。升级时间。