Ritesh Puri Ritesh Puri - 1 month ago 8
HTML Question

Converting first letter of a string to capital in xslt

I am new to XSLT and I need some help.

I have data stored in XML file and there is one attribute :

<clientName>JOHN GEORGE SMITH</clientName>

I am printing this name in my HTML file as follows:

<div>
<xsl:value-of select="clientName"/>
</div>


I want my output to be : John George Smith. I want the first letter to be capital for each word. I tried finding the solution online but couldn't find an appropriate way. Please help me with this. Thanks in advance.

Answer

The real problem here is not how to capitalize each word, but how to tokenize the given text to individual words.

If it can be assumed that words are always separated by a space - or at least by a string that ends with a space - then you could do it this way:

<xsl:template match="something">

    <!-- some stuff -->

    <div>
        <xsl:call-template name="capitalize">
            <xsl:with-param name="text" select="clientName"/>
        </xsl:call-template>
    </div>

    <!-- other stuff -->

</xsl:template>


<xsl:template name="capitalize">
    <xsl:param name="text"/>
    <xsl:param name="delimiter" select="' '"/>

    <xsl:variable name="upper-case" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
    <xsl:variable name="lower-case" select="'abcdefghijklmnopqrstuvwxyz'"/>

    <xsl:variable name="word" select="substring-before(concat($text, $delimiter), $delimiter)" />
    <xsl:if test="$word">
        <xsl:value-of select="translate(substring($word, 1, 1), $lower-case, $upper-case)"/>    
        <xsl:value-of select="translate(substring($word, 2), $upper-case, $lower-case)"/>
        </xsl:if>
    <xsl:if test="contains($text, $delimiter)">
        <xsl:value-of select="$delimiter"/>
        <!-- recursive call -->
        <xsl:call-template name="capitalize">
            <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

Note that this will fail with values such as:

<clientName>HILLARY RODHAM-CLINTON</clientName>
<clientName>HILLARY (RODHAM) CLINTON</clientName>
<clientName>GEORGE BUSH THE THIRD</clientName>
<clientName>CHARLES DE GAULLE</clientName>
<clientName>RENÉE ZELLWEGER</clientName>

and probably others I cannot think of at the moment.