Subject: RE: [xsl] Trying to find following sibling that ends in punctuation From: "Michael Kay" <mike@xxxxxxxxxxxx> Date: Sat, 4 Nov 2006 18:10:12 -0000 |
> 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, > '[.]|[:]|[!]|[?]')) 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, > '[."]|[!"]|[?"]|[.)]|[! > 1;]|[?)]')) > 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 = > '."'"><xsl:value-of select="'punct'" /></xsl:when> > <xsl:when test="$l_LastTwoCharacter = > '!"'"><xsl:value-of select="'punct'" /></xsl:when> > <xsl:when test="$l_LastTwoCharacter = > '?"'"><xsl:value-of select="'punct'" /></xsl:when> > <xsl:when test="$l_LastTwoCharacter = > '.)'"><xsl:value-of select="'punct'" /></xsl:when> > <xsl:when test="$l_LastTwoCharacter = > '!)'"><xsl:value-of select="'punct'" /></xsl:when> > <xsl:when test="$l_LastTwoCharacter = > '?)'"><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 = ('."', '!"', '?"', '.)', '!)', '?)'))" > > <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 |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Trying to find following , Marijan (Mario) Madu | Thread | Re: [xsl] question about identity t, Dimitre Novatchev |
RE: [xsl] Encoding issues with docu, Michael Kay | Date | Re: [xsl] CDATA or escape in the re, Kjetil Kjernsmo |
Month |