RE: [xsl] Split and Found unique values

Subject: RE: [xsl] Split and Found unique values
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Thu, 7 Dec 2006 19:28:07 -0000
In 2.0 you want distinct-values(for $c in target:row return
tokenize(@Category, '-')).

In 1.0 it's much harder. You certainly can't solve it the way you are
trying, because that involves a mutable variable. I would suggest a
two-phase solution: first to the tokenizing, using something like the EXSLT
str:tokenize() function or template, then do the duplicates elimination
using Muenchian grouping.

Michael Kay
http://www.saxonica.com/

> -----Original Message-----
> From: cruscio@xxxxxxxxx [mailto:cruscio@xxxxxxxxx] 
> Sent: 07 December 2006 14:01
> To: xsl-list
> Subject: [xsl] Split and Found unique values
> 
> Hi,
> I have an XML like this:
>  
>        <target:row Category='A-B-C-D'/>
>        <target:row Category='A-B'/>
>        <target:row Category='A-C-D'/>
>        <target:row Category='C'/>
>        <target:row Category='B-C-D'/>
>        <target:row Category='A'/>
>  
> with a combination of values separated by '-'. I need to 
> populate a listbox with unique values:
>  
> A
> B
> C
> D
>  
> I tried to save in a variable what was already processed and 
> skip it in case was found but the 'seen' variable is clean'd 
> up at the second round:
>  
> <xsl:key name='Category' match='xml/target' use='@Category'/> 
> <xsl:variable name='seen' select="''"/>
>  
>   <xsl:template name="my_templ_1">
>               <SELECT NAME="X" MULTIPLE="MULTIPLE">
>                   <xsl:for-each select='$Rowset[generate-id() 
> = generate-id(key("Category", @Category))]'>
>                      <xsl:call-template name="Split">
>                          <xsl:with-param name="strInput" 
> select="@Category"/>
>                      </xsl:call-template>
>                 </xsl:for-each>
>               </SELECT>
> </xsl:template>
>  
> <xsl:template name="Split">
>   <xsl:param name="strInput"/>
>   <xsl:param name="strDelimiter" select="'-'"/>
>   <xsl:param name="processed"/>
>   <xsl:variable name="strNextItem" 
> select="substring-before($strInput,$strDelimiter)"/>
>   <xsl:variable name="strOutput" 
> select="substring-after($strInput,$strDelimiter)"/>
> 
>   <xsl:variable name="seen" 
> select="concat($strNextItem,',',$processed)"/>
> 
>   <xsl:choose>
>     <xsl:when test='contains($strInput,$strDelimiter) and 
> not(contains($strInput,$seen))'>
>       <xsl:element name='OPTION'>
>        <xsl:value-of select="$strNextItem"/>
>       </xsl:element>
>       <xsl:call-template name="Split">
>        <xsl:with-param name="strInput" select="$strOutput"/>
>        <xsl:with-param name="strDelimiter" select="$strDelimiter"/>
>        <xsl:with-param name="processed" select="$seen"/>
>       </xsl:call-template>
>     </xsl:when>
>     <xsl:otherwise>
>       <xsl:if test="not(contains($strInput,$seen))">
>         <xsl:element name='OPTION'>
>          <xsl:value-of select="$strInput"/>
>         </xsl:element>
>        </xsl:if>
>     </xsl:otherwise>
>   </xsl:choose>
> </xsl:template>
> 
> Do you have a more elegant way?
>  
> Thank you.
> Carlos
> 
> 
> ------------------------------------------------------
> Passa a Infostrada. ADSL e Telefono senza limiti e senza 
> canone Telecom
> http://click.libero.it/infostrada07dic06

Current Thread