[xsl] Re: XSLT to find missing characters?

Subject: [xsl] Re: XSLT to find missing characters?
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Fri, 12 Jul 2002 07:09:00 -0700 (PDT)
--- "Kirk Allen Evans" <kaevans at xmlandasp dot net> wrote:

> 
> Was hoping for a few hundred extra pairs of eyes for this, maybe
> another
> solution.  I need to find the first element in a node set that
> matches
> a
> criteria.  If that node is not present in the node set, grab the next
> node
> in the node set alphabetically.  Here's the example:
> 
> <beers>
> 	<beer name="Amstel Light"/>
> 	<beer name="Budweiser"/>
> 	<beer name="Bud Lite"/>
> 	<beer name="Coors"/>
> 	<beer name="Michelob"/>
> 	<beer name="Miller Lite"/>
> 	<beer name="Sam Adams"/>
> </beers>
> 
> If "B" is sent as the parameter, "Budweiser" is output.  If "D" is
> sent,
> then "Michelob" is output.  If no matches are found, the first
> element
> is
> used for the output.  Here is my working stylesheet.  I was wondering
> if
> anyone could think of a different approach to solving this problem,
> perhaps
> with fewer string manipulations?
> 
> 
> <xsl:stylesheet version="1.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";;>
> 	<xsl:param name="searchLetter" select="'D'"/>
> 	<xsl:variable name="alphabet"
> select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
> 
> 	<xsl:output method="text"/>
> 	<xsl:template match="/">
> 		<xsl:variable name="beerName">
> 			<xsl:call-template name="CheckAlphabet">
> 				<xsl:with-param name="charPos"
> select="string-length(substring-before($alphabet,$searchLetter)) +
> 1"/>
> 			</xsl:call-template>
> 		</xsl:variable>
> 		<xsl:value-of select="$beerName"/>
> 	</xsl:template>
> 
> 	<xsl:template name="CheckAlphabet">
> 		<xsl:param name="charPos" select="1" />
> 		<xsl:variable name="alphabetLength" select="26" />
> 		<xsl:choose>
> 			<xsl:when test="$charPos &lt;= $alphabetLength">
> 				<xsl:choose>
> 					<xsl:when
>
test="/beers/beer[starts-with(@name,substring($alphabet,$charPos,1))][1]">
> 						<xsl:value-of
>
select="/beers/beer[starts-with(@name,substring($alphabet,$charPos,1))][1]/@
> name"/>
> 					</xsl:when>
> 					<xsl:otherwise>
> 						<xsl:call-template name="CheckAlphabet">
> 							<xsl:with-param name="charPos" select="$charPos + 1"/>
> 						</xsl:call-template>
> 					</xsl:otherwise>
> 				</xsl:choose>
> 			</xsl:when>
> 			<xsl:otherwise>
> 				<xsl:value-of select="/beers/beer[1]/@name"/>
> 			</xsl:otherwise>
> 		</xsl:choose>
> 	</xsl:template>
> </xsl:stylesheet>
> 
> Kirk Allen Evans
> http://www.xmlandasp.net
> "XML and ASP.NET", New Riders Publishing
> http://www.amazon.com/exec/obidos/ASIN/073571200X


Hi Kirk,

Yes, you can evaluate this with a single XPath expression:

/*/*
  [contains(concat($vStartLetter, 
                   substring-after($vAlphabet, $vStartLetter)
                   ), 
            substring(@name,1,1)
           )
  ][1] 

| 

 /*/*[1]
     [contains(substring-before($vAlphabet, $vStartLetter), 
               substring(/*/*[last()]/@name,1,1)
              )
     ]



Hope this helps.


=====
Cheers,

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

__________________________________________________
Do You Yahoo!?
Sign up for SBC Yahoo! Dial - First Month Free
http://sbc.yahoo.com

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


Current Thread