Re: [xsl] substring for whole words.

Subject: Re: [xsl] substring for whole words.
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Mon, 10 Mar 2003 08:32:59 -0800 (PST)
--- James Cummings <James.Cummings@xxxxxxxxx> wrote:
 
> I'm sure I'm just missing something obvious, but how do I get
> substring-before() or substring() to not split something in the
> middle of a word.  What I mean is, given an xml snippet of:
> 
> <foo>
> <wibble>This is only a test but it is a really really long
> one</wibble>
> <wibble>This is a different test, right.</wibble>
> </foo>
> 
> How do I produce:
> <ul>
> <li>This is only a test</li>
> <li>This is a different test</li>
> </ul>
> 
> I.e. Take the first five words as delimited by the whitespace?
> Any Hints?

Using FXSL (no need for EXSLT or whatever, only the xxx:node-set() ext.
is used) one would simply write the following:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
 xmlns:vendor="urn:schemas-microsoft-com:xslt"
 exclude-result-prefixes="vendor"  
>

   <xsl:import href="strSplit-to-Words.xsl"/>
<!-- This transformation must be applied to:
        testSplitToWords5.xml               
-->

   <xsl:output method="text"/>

    <xsl:template match="/">
    
      <xsl:for-each select="/*/*">
        <xsl:call-template name="getNWords">
          <xsl:with-param name="pStr" select="."/>
          <xsl:with-param name="pDelimiters" 
                          select="' ,'"/>
          <xsl:with-param name="pnumWords" select="5"/>
        </xsl:call-template>
        <xsl:text>&#xA;</xsl:text>
      </xsl:for-each>
    </xsl:template>
    
    <xsl:template name="getNWords">
      <xsl:param name="pStr"/>
      <xsl:param name="pDelimiters"/>
      <xsl:param name="pnumWords" select="1"/>
      
      <xsl:variable name="vrtfWords">
        <xsl:call-template name="str-split-to-words">
          <xsl:with-param name="pStr" select="$pStr"/>
          <xsl:with-param name="pDelimiters" 
                          select="$pDelimiters"/>
        </xsl:call-template>
      </xsl:variable>
      
      <xsl:for-each 
        select="vendor:node-set($vrtfWords)/*
                   [position() &lt;= $pnumWords]
                                          /text()">
        <xsl:value-of select="concat(., ' ')"/>
      </xsl:for-each>
      
    </xsl:template>
</xsl:stylesheet>

When this transformation is applied on your xml.source:

<foo>
  <wibble>This is only a test but it is a really really long
one</wibble>
  <wibble>This is a different test, right.</wibble>
</foo>

The result is:

This is only a test 
This is a different test 


Hope this helped.





=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL

__________________________________________________
Do you Yahoo!?
Yahoo! Tax Center - forms, calculators, tips, more
http://taxes.yahoo.com/

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread