0

我将逗号分隔的字符串拆分如下:

<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) &gt; 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..

还是我太笨了,我什至根本不理解这个递归过程??

4

2 回答 2

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>

现在,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) &gt; 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

于 2013-08-30T06:51:24.000 回答
2

您需要 XSLT 2.0。在 XSLT 1.0 中,没有数据类型可以处理字符串序列。您可以创建一个包含变量中的字符串的节点集,如果您有 exslt:node-set() 扩展,那么您可以处理节点集,但它是一个糟糕的替代品。是时候升级了。

于 2013-08-29T21:43:20.463 回答