5

I have an XML like

<emps>
<emp id='3432'>
 <fname>Jack</fname>
 <lname>Dawson</lname>
<emp>
<emp id='1122'>
 <fname>Jack</fname>
 <lname>Thompson</lname>
<emp>
<emps>

I am developing a web application which searches this xml based on the first name entered and comes up with a resultant page. To achieve this I have written an xslt to transform the XML to HTML based on the input search string which is passed as a variable named srchStr.

<xsl:template match="employees">
  <xsl:for-each select="emp[fname=$srchStr]">
<tr>
   <xsl:variable name="id">
    <xsl:value-of select="@id" />
   </xsl:variable>
   <td>
    <a href='detailSearch.do?id={$id}'>
     <xsl:value-of select="fname" />
     ,
     <xsl:value-of select="lname" />
    </a>
   </td>

  </tr>
</xsl:for-each
</xsl:template>

But the user may enter the name either in upper case or lower case. So how to convert the first name inside the xml tag fname to lower case and do the comparison?

Can some one put a code snippet to use fn:lower-case inside my xsl.

Bala
  • 51
  • 1
  • 1
  • 2
  • 1
    Duplicate of http://stackoverflow.com/questions/586231/how-can-i-convert-a-string-to-upper-or-lower-case-with-xslt – Lukas Eder Feb 25 '11 at 13:06

2 Answers2

10

To convert a string to lower case or uppercase you can use the XPath 1.0 function translate:

First define your alphabets for lower case and upper case letters. Note that the position of each pair of characters needs to be the same:

<xsl:variable name="lcletters">abcdefghijklmnopqrstuvwxyz</xsl:variable>
<xsl:variable name="ucletters">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable>

Then you can convert to upper case:

<xsl:value-of select="translate($toconvert,$lcletters,$ucletters)"/>

or to lower case

<xsl:value-of select="translate($toconvert,$ucletters,$lcletters)"/>
Dirk Vollmar
  • 172,527
  • 53
  • 255
  • 316
  • This doesn't work when there isn't a one-to-one mapping between lowercase and uppercase letters. The German ettsett (ß) is exclusively lowercase and the upper-case version is "SS". (Two 'S' letters.) Considering the number of Unicode letters, and the likelihood of even US-only sites/services encountering someone with accents in their names, this is a non-viable solution unless you exclusively care about anglicanized spellings of names. – yam655 Jan 27 '14 at 15:24
  • @yam655: Indeed, translating a single character into two characters will not work using this approach. An option could be to add a mapping to the LATIN CAPITAL LETTER SHARP S Unicode code character (U+1E9E) which has been added back in 2008. By the way, accented characters will work, they just have to be in the list as Tomalak pointed out. But after all, XSLT/XPath 1.0 is a very limited platform, and I would certainly recommend doing case conversions using a dedicated library with good support for I18N. – Dirk Vollmar Jan 27 '14 at 15:57
  • that just showcases the problem with the translate() approach, though. Once you deal with non-English languages, you start having multiple mappings for things which are linguistically the same. In German, "ß" should compare the same as "ss", but people can guess that. The bigger problems come from accented letters, where you have the possibility of a set of non-advancing accents on top of a base letter versus a single codepoint. ('Ê' vs. the non-advancing '^' and the standard 'E', etc.) I agree, better to use a library with explicit I18N support. IMO, translate() should be avoided. – yam655 Jan 27 '14 at 17:05
4

emp[lower-case(fname)=lower-case($srchStr)]

Or, if you have XPath 1.0 only, you may try using translate like here: http://geekswithblogs.net/TimH/archive/2006/07/06/84229.aspx

Be warned though, the example with translate would not work on names with accents (like mine :)

František Žiačik
  • 7,511
  • 1
  • 34
  • 59