XSL:从分隔字符串构造一个数组

时间:2011-11-29 17:02:11

标签: arrays xslt

我有一个字符串,其中的数据由"|"之类的分隔符分隔,并存在于变量中。 我想在XSL中创建一个数组,方法是根据分隔符划分上面的字符串,并希望在for循环中访问它。

请在这方面帮助我。 如果有人需要更多信息,请告诉我。

字符串为"Test1|Test2|Test3|Test4",并希望获得一个变量TEMP,该变量将是字符串中的数据数组,并且希望以TEMP[index]的形式进行访问。

我试图在论坛成员的输入之后使用tokenize函数来从字符串中获取值,但是没有成功。我没有在循环中获取字符串值。

<xsl:variable name="temp" xmlns:str="http://exslt.org/strings" select="str:tokenize(normalize-space(' Test1$,$Test2$,$Test3$,$Test4 '),'$,$')"/>
<xsl:for-each xmlns:str="http://exslt.org/strings" select="str:split(normalize-space(' 1$,$2$,$3$,$4$,$5$,$6 '),'$,$')">
    <xsl:variable name="index" select="position()"/>
    <xsl:value-of select="$temp[$index]"/>
</xsl:for-each>

此致 拉克什曼

4 个答案:

答案 0 :(得分:14)

  

字符串是"Test1|Test2|Test3|Test4",并希望得到一个变量   TEMP这将是字符串中的数据数组,并希望如此   以TEMP[index]进行访问。

为一个好问题+1。

此XSLT 1.0转换

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:variable name="vrtfTokens">
  <xsl:apply-templates/>
 </xsl:variable>

 <xsl:variable name="vTokens" select=
   "ext:node-set($vrtfTokens)/*"/>
 <xsl:template match="/">
  <xsl:for-each select=
   "document('')//node()[not(position() > count($vTokens))]
   ">
   <xsl:variable name="vPos" select="position()"/>
    <xsl:copy-of select="$vTokens[$vPos+0]"/>
  </xsl:for-each>
 </xsl:template>

 <xsl:template match="text()" name="split">
  <xsl:param name="pText" select="."/>

  <xsl:if test="string-length($pText)">
   <xsl:variable name="vToken" select=
    "substring-before(concat($pText,'|'), '|')"/>
   <s><xsl:value-of select="$vToken"/></s>

   <xsl:call-template name="split">
    <xsl:with-param name="pText" select=
    "substring-after($pText, '|')"/>
   </xsl:call-template>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

应用于此XML文档时

<t>Test1|Test2|Test3|Test4</t>

创建一个变量vTokens,其中包含名为s的元素,每个元素都将唯一的文本子句作为“|” - 定界字符串"Test1|Test2|Test3|Test4"的标记。

然后转换使用“索引”输出每个s元素。

产生了想要的正确结果

<s>Test1</s>
<s>Test2</s>
<s>Test3</s>
<s>Test4</s>

如果我们只需要令牌(字符串)本身,我们将使用:

string($vTokens[someIndex])

答案 1 :(得分:9)

它不是数组而是序列,您必须拥有XSLT 2.0处理器。您可以使用tokenize()功能:

<xsl:variable name="temp" as="xs:string*" select="tokenize('Test1|Test2|Test3|Test4','\|')"/>

您还可以传递字符串变量作为tokenize的第一个参数。

然后你使用:

<xsl:value-of select="$temp[$index]"/>

编辑:除非你使用某些扩展名,否则无法在xslt 1.0中实现此目的。

答案 2 :(得分:3)

该任务称为标记化,在XSLT 2.0中,您可以使用tokenize('Test1|Test2|Test3|Test4', '\|'),使用XSLT 1.0,您可以使用http://www.exslt.org/str/functions/tokenize/index.html之类的扩展名。

答案 3 :(得分:2)

我试试这个,我修改了&#34; Dimitre Novatchev&#34;代码,并为我工作:(请原谅我的英语)

<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="1.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:msxsl="urn:schemas-microsoft-com:xslt"
            exclude-result-prefixes="msxsl">

<xsl:template match="/*">
        <xsl:variable name="_keywords">
            <xsl:call-template name="split-to-values">
                <xsl:with-param name="_text" select="Keywords-comma-separated"/>
            </xsl:call-template>
        </xsl:variable>

        <xsl:for-each select="msxsl:node-set($_keywords)/value">
            <xsl:variable name="_keyword" select="."/>
            <!-- ANY CODE -->
        </xsl:for-each>
</xsl:template>

<xsl:template match="text()" name="split-to-values">
    <xsl:param name="_text"/>

    <xsl:if test="string-length($_text)">
        <xsl:variable name="_value" select="substring-before($_text, ',')"/>
        <xsl:variable name="_next" select="substring-after($_text, ',')"/>
        <value>
            <xsl:value-of select="$_value"/>
        </value>

        <xsl:call-template name="split-to-values">
            <xsl:with-param name="_text" select="$_next"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

我希望它可以帮到你

@Bugude问

  

我有一个字符串,其中数据由分隔符分隔,例如&#34; |&#34;和   存在于变量中。我想在XSL中创建一个数组   通过基于分隔符划分上面的字符串并且想要   在for循环中访问相同的

然后字符串可能是:&#34; alfa,beta,gama,delta&#34;

分隔符显示在变量中:

<xsl:variable name="_delimiter">,</xsl:variable>

我将模板修改为:

<xsl:template match="text()" name="split-to-values">
    <xsl:param name="_text"/>
    <xsl:param name="_delimiter"/>

    <xsl:if test="string-length($_text)">
        <xsl:variable name="_value" select="substring-before($_text, $_delimiter)"/>
        <xsl:variable name="_next" select="substring-after($_text, $_delimiter)"/>
        <value>
            <xsl:value-of select="$_value"/>
        </value>

        <xsl:call-template name="split-to-values">
            <xsl:with-param name="_text" select="$_next"/>
            <xsl:with-param name="_delimiter" select="$_delimiter"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

我们可以像使用for

一样访问节点
<xsl:template match="/*">
        <!-- _keyword as set a node -->
        <xsl:variable name="_keywords">
            <xsl:call-template name="split-to-values">
                <xsl:with-param name="_text" select="'alfa,beta,gama,delta'"/>
                <xsl:with-param name="_delimiter" select="$_delimiter"/>
            </xsl:call-template>
        </xsl:variable>

        <xsl:for-each select="msxsl:node-set($_keywords)/value">
            <xsl:variable name="_keyword" select="."/>
            <!-- ANY CODE -->
            <xsl:value-of select="$_keyword"/>
        </xsl:for-each>
</xsl:template>