This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: XSLT to find missing characters?
- From: Dimitre Novatchev <dnovatchev at yahoo dot com>
- To: xsl-list at lists dot mulberrytech dot com
- Date: Fri, 12 Jul 2002 07:09:00 -0700 (PDT)
- Subject: [xsl] Re: XSLT to find missing characters?
- Reply-to: xsl-list at lists dot mulberrytech dot com
--- "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 <= $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