XSL技术实现:从逗号分隔字符串创建可遍历数组
Hey there! Let's figure out how to turn that comma-separated string into something you can loop over with <xsl:for-each> in XSL. The solution depends on which XSLT version you're working with, so I'll break down both common scenarios:
XSLT 2.0+ (The Easier Route)
If you're using XSLT 2.0 or later (like 3.0), you can use the built-in tokenize() function to split the string directly into a sequence of strings—which you can iterate over right away.
Here's a complete example:
<!-- Define your original string variable --> <xsl:variable name="string-variable" select="'hello, hello, good Evening, good evening'" /> <!-- Split the string, handling spaces around commas --> <xsl:variable name="split-sequence" select="tokenize($string-variable, '\s*,\s*')" /> <!-- Loop through each item in the sequence --> <xsl:for-each select="$split-sequence"> <list-item> <xsl:value-of select="." /> </list-item> </xsl:for-each>
Quick breakdown:
- The regex
\s*,\s*matches a comma surrounded by any number of whitespace characters (spaces, tabs, etc.). This ensures you don't end up with extra spaces in your split values. - The
tokenize()function returns a sequence, so<xsl:for-each>can directly select it without extra steps.
XSLT 1.0 (No Native Tokenize? Use a Recursive Template)
XSLT 1.0 doesn't have a built-in tokenize() function, so we need to create a recursive template to split the string into a node set (since 1.0 works with nodes instead of sequences).
Here's how to do it:
<!-- Your original string variable --> <xsl:variable name="string-variable" select="'hello, hello, good Evening, good evening'" /> <!-- Call the split template to generate a node set --> <xsl:variable name="split-nodes"> <xsl:call-template name="split-string"> <xsl:with-param name="input" select="$string-variable" /> <xsl:with-param name="delimiter" select="', '" /> <!-- Adjust if your delimiter has different spacing --> </xsl:call-template> </xsl:variable> <!-- Loop through the generated <item> nodes --> <xsl:for-each select="$split-nodes/item"> <list-item> <xsl:value-of select="." /> </list-item> </xsl:for-each> <!-- Recursive template to split the string into nodes --> <xsl:template name="split-string"> <xsl:param name="input" /> <xsl:param name="delimiter" select="', '" /> <xsl:choose> <!-- If the input still contains the delimiter --> <xsl:when test="contains($input, $delimiter)"> <!-- Extract the part before the delimiter --> <item> <xsl:value-of select="substring-before($input, $delimiter)" /> </item> <!-- Recurse with the remaining part of the string --> <xsl:call-template name="split-string"> <xsl:with-param name="input" select="substring-after($input, $delimiter)" /> <xsl:with-param name="delimiter" select="$delimiter" /> </xsl:call-template> </xsl:when> <!-- No more delimiters left—add the final item --> <xsl:otherwise> <item> <xsl:value-of select="$input" /> </item> </xsl:otherwise> </xsl:choose> </xsl:template>
Notes for XSLT 1.0:
- If your XSLT processor supports the EXSLT
str:tokenizeextension, you can simplify this by usingstr:tokenize($string-variable, '\s*,\s*')—just add the namespacexmlns:str="http://exslt.org/strings"to your stylesheet. But not all processors support this, so the recursive template is more reliable. - To handle leading/trailing commas or extra spaces, you can add a step to trim the input string first (using a helper template for trimming in 1.0).
内容的提问来源于stack exchange,提问作者Robertone
相关产品推荐
相关产品推荐

