Subject: Re: split string to whole words based on length
From: "andrew welch" <andrew.j.welch@xxxxxxxxx>
Date: Wed, 26 Apr 2006 18:00:51 +0100
|
On 4/26/06, David Carlisle <davidc@xxxxxxxxx> wrote:
>
>
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
> version="2.0"
>
> >
>
>
> <xsl:variable name="str" select="'one,two,three,four,five'" as="xs:string"
xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
> <xsl:variable name="length" select="10" as="xs:integer"
xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
>
> <xsl:output indent="yes"/>
>
> <xsl:template name="x">
> <xsl:analyze-string select="$str" regex=".{{0,{$length}}},">
> <xsl:matching-substring>
> <words><xsl:value-of
select="substring(.,1,string-length(.)-1)"/></words>
> </xsl:matching-substring>
> <xsl:non-matching-substring>
> <words><xsl:value-of select="."/></words>
> </xsl:non-matching-substring>
> </xsl:analyze-string>
> </xsl:template>
>
> </xsl:stylesheet>
This fails for the input:
<words>
<word>aaaaaaaaaaaaaaaaaaaa</word>
<word>aaaaaaaaaaaaaaaaaaaaa</word>
<word>aaaaaaaaaaaaaaaaaaaaa</word>
<word>aaaaaaaaaaaaaaaaaaaaaaaaaaaa</word>
<word>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</word>
<word>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</word>
<word>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</word>
<word>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</word>
</words>
It creates too many output elements.
Here's my attempt which is recursive and a bit large (which prompted
the question) but it does get the right answer:
<xsl:template name="splitString">
<xsl:param name="str"/>
<xsl:param name="length" select="$length"/>
<xsl:param name="delim" select="','"/>
<xsl:choose>
<xsl:when test="string-length($str) <= $length">
<keywords><xsl:value-of select="$str"/></keywords>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="substring" select="substring($str, 1, $length)"/>
<xsl:choose>
<xsl:when test="starts-with(substring-after($str, $substring), $delim)">
<!-- The split has occurred exactly on the delimeter -->
<keyword><xsl:value-of select="$substring"/></keyword>
<xsl:call-template name="splitString">
<xsl:with-param name="str" select="substring-after($str,
concat($substring, ','))"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- The split hass occurred mid word -->
<xsl:variable name="subsubstring" select="for $x in
tokenize($substring, $delim) return concat($x, ',')[position() !=
last()]"/>
<xsl:analyze-string select="$substring" regex="(.*),">
<xsl:matching-substring>
<keyword><xsl:value-of select="regex-group(1)"/></keyword>
<xsl:call-template name="splitString">
<xsl:with-param name="str" select="substring-after($str,
concat(regex-group(1), ','))"/>
</xsl:call-template>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
|