[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

RE: Trying to find following sibling that ends in pun

Subject: RE: Trying to find following sibling that ends in punctuation
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Sat, 4 Nov 2006 18:10:12 -0000
xsl when test following sibling
> Michael here is the function but it has worked perfectly(or 
> as perfectly as can be) in other instances.

Let's walk through it and see what it does if the argument is an empty
sequence.
> 
>     <xsl:function name="f:f_StringEndsWith" as="xs:string">
> 
>         <!-- p_String to test -->
>         <xsl:param name="p_String" />

There's no "as" attribute: it might be a good idea to add one. You'll have
to decide whether to use xs:string or xs:string? - ie whether an empty
sequence is allowed or not. 
> 
>         <!-- get the last character -->
>         <xsl:variable name="l_LastCharacter" 
> select="substring($p_String, string-length($p_String), 1)" />

If the param is (), this variable will be "" (the zero length string)
> 
>         <!-- get the last two characters -->
>         <xsl:variable name="l_LastTwoCharacter" 
> select="substring($p_String, string-length($p_String) - 1, 2)" />

If the param is (), this variable will be "" (the zero length string)
> 
>         <!-- . : ! ? -->
>         <xsl:variable name="l_LastCharacterIs" select="if 
> (matches($l_LastCharacter, 
> '[&#46;]|[&#58;]|[&#33;]|[&#63;]')) then 'punct' else 'noPunct'" />

If the param is () there will be no match, so the value will be "noPunct"
> 
>         <!-- ." !" ?" .) !) ?) -->
>         <!--xsl:variable name="l_LastTwoCharacterAre" 
> select="if (matches($l_LastTwoCharacter,
> '[&#46;&#34;]|[&#33;&#34;]|[&#63;&#34;]|[&#46;&#41;]|[&#33;&#4
> 1;]|[&#63;&#41;]'))
> then 'punct' else 'noPunct'" /-->

If the param is () there will be no match, so the value will be "noPunct"
> 
>         <!-- the above failed in a couple of instances and so 
> the var and choose below works. it is in longhand for ease of 
> maintaining -->
>         <!-- ." !" ?" .) !) ?) -->
>         <xsl:variable name="l_LastTwoCharacterAre">
>             <xsl:choose>
>                 <xsl:when test="$l_LastTwoCharacter = 
> '&#46;&#34;'"><xsl:value-of select="'punct'" /></xsl:when>
>                 <xsl:when test="$l_LastTwoCharacter = 
> '&#33;&#34;'"><xsl:value-of select="'punct'" /></xsl:when>
>                 <xsl:when test="$l_LastTwoCharacter = 
> '&#63;&#34;'"><xsl:value-of select="'punct'" /></xsl:when>
>                 <xsl:when test="$l_LastTwoCharacter = 
> '&#46;&#41;'"><xsl:value-of select="'punct'" /></xsl:when>
>                 <xsl:when test="$l_LastTwoCharacter = 
> '&#33;&#41;'"><xsl:value-of select="'punct'" /></xsl:when>
>                 <xsl:when test="$l_LastTwoCharacter = 
> '&#63;&#41;'"><xsl:value-of select="'punct'" /></xsl:when>
>                 <xsl:otherwise><xsl:value-of select="'noPunct'" 
> /></xsl:otherwise>
>             </xsl:choose>
>         </xsl:variable>

This is horrible. If your code doesn't work, find out why, don't just add
another version of the same logic! 

In fact, the best way of testing whether your variable $l_LastTwoCharacter =
is equal to one of these strings is simply:

test="($l_LastTwoCharacter = ('.&quot;', '!&quot;', '?&quot;', '.)', '!)',
'?)'))"
> 
>         <xsl:choose>
>             <xsl:when test="($l_LastCharacterIs = 'punct') or 
> ($l_LastTwoCharacterAre = 'punct')"><xsl:value-of select="'punct'" 
> /></xsl:when>
>             <xsl:otherwise><xsl:value-of select="'noPunct'" 
> /></xsl:otherwise>
>         </xsl:choose>

It looks as if my theory was correct. When you call the function with (), it
will return "noPunct", and therefore your recursive template will recurse
for ever.

Note also, you should be using <xsl:sequence> rather than <xsl:value-of> in
this code. There's no reason to be creating text nodes when you only want
strings.

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

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Cast Your Vote

We need your help – Vote for DataDirect XML Products!

  • Best SOA or XML site

Winners and finalists announced at SOA World Conference in November.

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2007 All Rights Reserved.