XSLT konvertering til store/små bogstaver

Den almene metode til at konvertere strenge til f.eks. små bogstaver (minuskler) for at udføre en sammenligning, eller blot for at præsentere det transformerede resultat på den vis, er at benytte sig af XPath funktionen translate. Flere steder finder man netop denne løsning implementeret og den fremføres ofte som en god måde at konvertere strenge til f.eks. minuskler, blandt andet i XSLT 2nd Edition Programmer’s Reference af Michael Kay, der må siges at være “biblen” indenfor XSLT-området.

En XSLT transformationsfil der skal kunne foretage konvertering af danske strenge vil typisk indeholde:

<!-- translate strenge -->
<xsl:variable name="lcletters">abcdefghijklmnopqrstuvwxyzæøå</xsl:variable>
<xsl:variable name="ucletters">ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ</xsl:variable>
...
<!-- til versaler -->
<xsl:value-of select="translate($toconvert,$lcletters,$ucletters)"/>
...
<!-- til minuskler -->
<xsl:value-of select="translate($toconvert,$ucletters,$lcletters)"/>

Problemet med translate-løsningen er, at den ikke tager højde for andre tegn end dem man eksplicit angiver – og det kan være en stor opgave hvis tegnsættet der anvendes er UTF-8 eller blot ISO-Latin-1. Der er henholdsvist flere tusinde / hundrede tegn i disse tegnsæt. Tegn der ikke er angivet slipper uændrede igennem transformationen med translate.

Med nedenstående XML-datafil i hånden vil førnævnte translate-strenge fejle, da “umlaut”-tegnene ikke er dækkede.

<?xml version="1.0" encoding="UTF-8"?>
<items>
  <item>
    <title>Dette er danske tegn æøåÆØÅ</title>
  </item>
  <item>
    <title>Dette er andre tegn üöäÜÖÄ</title>
  </item>
</items>

En anden metode jeg derfor har nørklet med i dag, der dog kun fungerer i Internet Explorer, er at indlejre et JavaScript i XSLT transformationsfilen, og herfra udnytte JavaScript’s toLowerCase() funktion. Firefox har endnu ikke understøttelse for XSLT 1.1 <xsl:script>, hvorimod Internet Explorer tilbyder en Microsoft-proprietær implementation der fungerer ganske udemærket, nemlig <msxsl:script>.

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:tns="urn:thisnamespace:tns"
exclude-result-prefixes="tns msxsl">
<msxsl:script language="JavaScript" implements-prefix="tns">
function lCase(item) {
  return (''+item).toLowerCase(); 
}
</msxsl:script>
<xsl:template match="/">
  <xsl:for-each select="items/item">
    <xsl:variable name="aparam" select="title"/>
    <xsl:value-of select="tns:lCase(string($aparam))"/><br />
  </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Du kan ved brug af, Internet Explorer (version 6 eller nyere), se resultatet af at udføre XSL + JavaScript transformationen her. Det forventede resultat er at samtlige tegn i XML-datafilen er konverteret til minuskler.

Jeg leder fortsat efter en elegant cross-browser løsning, men for nuværende er ovenstående dækkende pga. krav til opgaven specifikt kun er rettet imod slutbrugere der anvender Internet Explorer.