There are some developers out there who believe that XML is the greatest "innovation" in computer science since electricity. Believing that, apparently, all data and communication are best represented as strings with angle-brackets, they'll go to great strides to ensure that this "technology" is applied liberally throughout systems they build. Undeterred by the inherent constraints of a data interchange format and its related transforms, they'll make sure that XML is not only the driving force behind their projects, but their raison d'être.

Joe works with one such a developer, and presents us i18n.xsl, the end result of his colleague's six straight days of work trying to get his fully-XSL solution to properly display HTML characters.


<xsl:template name="Replace">
  <xsl:param name="string" select="''"/>
  <xsl:param name="pattern" select="''"/>
  <xsl:param name="replacement" select="''"/>
  <xsl:choose>
  <xsl:when test="$pattern!='' and $string!='' and contains($string, $pattern)">
    <xsl:value-of select="substring-before($string, $pattern)"/>
     
    <xsl:copy-of select="$replacement"/>
    <xsl:call-template name="Replace">
      <xsl:with-param name="string" select="substring-after($string, $pattern)"/>
      <xsl:with-param name="pattern" select="$pattern"/>
      <xsl:with-param name="replacement" select="$replacement"/>
    </xsl:call-template>
  </xsl:when>
  <xsl:otherwise>
    <xsl:value-of select="$string"/>
  </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template name="ReplaceLCWithHTML">
    <xsl:param name="input" select="''"/>
    <xsl:choose>
    <xsl:when test="$input!=''">
        <xsl:call-template name="Replace">
            <xsl:with-param name="string">
            <xsl:call-template name="Replace">
                <xsl:with-param name="string">
                <xsl:call-template name="Replace">
                    <xsl:with-param name="string">
                    <xsl:call-template name="Replace">
                        <xsl:with-param name="string">
                        <xsl:call-template name="Replace">
                            <xsl:with-param name="string">
                            <xsl:call-template name="Replace">
                                <xsl:with-param name="string">
                                <xsl:call-template name="Replace">
                                    <xsl:with-param name="string">
                                    <xsl:call-template name="Replace">
                                        <xsl:with-param name="string">
                                        <xsl:call-template name="Replace">
                                            <xsl:with-param name="string">
                                            <xsl:call-template name="Replace">
                                                <xsl:with-param name="string">
                                                <xsl:call-template name="Replace">
                                                    <xsl:with-param name="string">
                                                    <xsl:call-template name="Replace">
                                                        <xsl:with-param name="string">
                                                        <xsl:call-template name="Replace">
                                                            <xsl:with-param name="string">
                                                            <xsl:call-template name="Replace">
                                                                <xsl:with-param name="string">
                                                                <xsl:call-template name="Replace">
                                                                    <xsl:with-param name="string">
                                                                    <xsl:call-template name="Replace">
                                                                        <xsl:with-param name="string">
                                                                        <xsl:call-template name="Replace">
                                                                            <xsl:with-param name="string">
                                                                            <xsl:call-template name="Replace">
                                                                                <xsl:with-param name="string">
                                                                                <xsl:call-template name="Replace">
                                                                                    <xsl:with-param name="string">
                                                                                    <xsl:call-template name="Replace">
                                                                                        <xsl:with-param name="string">
                                                                                        <xsl:call-template name="Replace">
                                                                                            <xsl:with-param name="string">
                                                                                            <xsl:call-template name="Replace">
                                                                                                <xsl:with-param name="string">
                                                                                                <xsl:call-template name="Replace">
                                                                                                    <xsl:with-param name="string">
                                                                                                    <xsl:call-template name="Replace">
                                                                                                        <xsl:with-param name="string">
                                                                                                        <xsl:call-template name="Replace">
                                                                                                            <xsl:with-param name="string">
                                                                                                            <xsl:call-template name="Replace">
                                                                                                                <xsl:with-param name="string" select="$input"/>
                                                                                                                <xsl:with-param name="pattern" select="'à'"/>
                                                                                                                <xsl:with-param name="replacement" select="'&agrave;'"/>
                                                                                                            </xsl:call-template>
                                                                                                            </xsl:with-param>
                                                                                                            <xsl:with-param name="pattern" select="'á"/>
                                                                                                            <xsl:with-param name="replacement" select="'&aacute;'"/>
                                                                                                        </xsl:call-template>
                                                                                                        </xsl:with-param>
                                                                                                        <xsl:with-param name="pattern" select="'â'"/>
                                                                                                        <xsl:with-param name="replacement" select="'&acirc;'"/>
                                                                                                    </xsl:call-template>
                                                                                                    </xsl:with-param>
                                                                                                    <xsl:with-param name="pattern" select="'è'"/>
                                                                                                    <xsl:with-param name="replacement" select="'&egrave;'"/>
                                                                                                </xsl:call-template>
                                                                                                </xsl:with-param>
                                                                                                <xsl:with-param name="pattern" select="'é'"/>
                                                                                                <xsl:with-param name="replacement" select="'&eacute;'"/>
                                                                                            </xsl:call-template>
                                                                                            </xsl:with-param>
                                                                                            <xsl:with-param name="pattern" select="'ê'"/>
                                                                                            <xsl:with-param name="replacement" select="'&ecirc;'"/>
                                                                                        </xsl:call-template>
                                                                                        </xsl:with-param>
                                                                                        <xsl:with-param name="pattern" select="'ì'"/>
                                                                                        <xsl:with-param name="replacement" select="'&igrave;'"/>
                                                                                    </xsl:call-template>
                                                                                    </xsl:with-param>
                                                                                    <xsl:with-param name="pattern" select="'í'"/>
                                                                                    <xsl:with-param name="replacement" select="'&iacute;'"/>
                                                                                </xsl:call-template>
                                                                                </xsl:with-param>
                                                                                <xsl:with-param name="pattern" select="'î'"/>
                                                                                <xsl:with-param name="replacement" select="'&icirc;'"/>
                                                                            </xsl:call-template>
                                                                            </xsl:with-param>
                                                                            <xsl:with-param name="pattern" select="'ò'"/>
                                                                            <xsl:with-param name="replacement" select="'&ograve;'"/>
                                                                        </xsl:call-template>
                                                                        </xsl:with-param>
                                                                        <xsl:with-param name="pattern" select="'ó'"/>
                                                                        <xsl:with-param name="replacement" select="'&oacute;'"/>
                                                                    </xsl:call-template>
                                                                    </xsl:with-param>
                                                                    <xsl:with-param name="pattern" select="'ô'"/>
                                                                    <xsl:with-param name="replacement" select="'&ocirc;'"/>
                                                                </xsl:call-template>
                                                                </xsl:with-param>
                                                                <xsl:with-param name="pattern" select="'ù'"/>
                                                                <xsl:with-param name="replacement" select="'&ugrave;'"/>
                                                            </xsl:call-template>
                                                            </xsl:with-param>
                                                            <xsl:with-param name="pattern" select="'ú'"/>
                                                            <xsl:with-param name="replacement" select="'&uacute;'"/>
                                                        </xsl:call-template>
                                                        </xsl:with-param>
                                                        <xsl:with-param name="pattern" select="'û'"/>
                                                        <xsl:with-param name="replacement" select="'&ucirc;'"/>
                                                    </xsl:call-template>
                                                    </xsl:with-param>
                                                    <xsl:with-param name="pattern" select="'ý'"/>
                                                    <xsl:with-param name="replacement" select="'&yacute;'"/>
                                                </xsl:call-template>
                                                </xsl:with-param>
                                                <xsl:with-param name="pattern" select="'œ'"/>
                                                <xsl:with-param name="replacement" select="'&oelig;'"/>
                                            </xsl:call-template>
                                            </xsl:with-param>
                                            <xsl:with-param name="pattern" select="'ç'"/>
                                            <xsl:with-param name="replacement" select="'&ccedil;'"/>
                                        </xsl:call-template>
                                        </xsl:with-param>
                                        <xsl:with-param name="pattern" select="'™'"/>
                                        <xsl:with-param name="replacement" select="'&trade;'"/>
                                    </xsl:call-template>
                                    </xsl:with-param>
                                    <xsl:with-param name="pattern" select="'¢'"/>
                                    <xsl:with-param name="replacement" select="'&cent;'"/>
                                </xsl:call-template>
                                </xsl:with-param>
                                <xsl:with-param name="pattern" select="'©'"/>
                                <xsl:with-param name="replacement" select="'&copy;'"/>
                            </xsl:call-template>
                            </xsl:with-param>
                            <xsl:with-param name="pattern" select="'®'"/>
                            <xsl:with-param name="replacement" select="'&reg;'"/>
                        </xsl:call-template>
                        </xsl:with-param>
                        <xsl:with-param name="pattern" select="'°'"/>
                        <xsl:with-param name="replacement" select="'&deg;'"/>
                    </xsl:call-template>
                    </xsl:with-param>
                    <xsl:with-param name="pattern" select="'&nbsp;'"/>
                    <xsl:with-param name="replacement" select="' '"/>
                </xsl:call-template>
                </xsl:with-param>
                <xsl:with-param name="pattern" select="'&shy;'"/>
                <xsl:with-param name="replacement" select="' '"/>
            </xsl:call-template>
            </xsl:with-param>
            <xsl:with-param name="pattern" select="'·'"/>
            <xsl:with-param name="replacement" select="'&middot;'"/>
        </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="$input"/>
    </xsl:otherwise>
    </xsl:choose>
</xsl:template>
        
<xsl:template name="ReplaceUCWithHTML">
    <xsl:param name="input" select="''"/>
    <xsl:choose>
    <xsl:when test="$input!=''">
    <xsl:call-template name="Replace">
        <xsl:with-param name="string">
        <xsl:call-template name="Replace">
            <xsl:with-param name="string">
            <xsl:call-template name="Replace">
                <xsl:with-param name="string">
                <xsl:call-template name="Replace">
                    <xsl:with-param name="string">
                    <xsl:call-template name="Replace">
                        <xsl:with-param name="string">
                        <xsl:call-template name="Replace">
                            <xsl:with-param name="string">
                            <xsl:call-template name="Replace">
                                <xsl:with-param name="string">
                                <xsl:call-template name="Replace">
                                    <xsl:with-param name="string">
                                    <xsl:call-template name="Replace">
                                        <xsl:with-param name="string">
                                        <xsl:call-template name="Replace">
                                            <xsl:with-param name="string">
                                            <xsl:call-template name="Replace">
                                                <xsl:with-param name="string">
                                                <xsl:call-template name="Replace">
                                                    <xsl:with-param name="string">
                                                    <xsl:call-template name="Replace">
                                                        <xsl:with-param name="string">
                                                        <xsl:call-template name="Replace">
                                                            <xsl:with-param name="string">
                                                            <xsl:call-template name="Replace">
                                                                <xsl:with-param name="string">
                                                                <xsl:call-template name="Replace">
                                                                    <xsl:with-param name="string">
                                                                    <xsl:call-template name="Replace">
                                                                        <xsl:with-param name="string">
                                                                        <xsl:call-template name="Replace">
                                                                            <xsl:with-param name="string">
                                                                            <xsl:call-template name="Replace">
                                                                                <xsl:with-param name="string">
                                                                                <xsl:call-template name="Replace">
                                                                                    <xsl:with-param name="string" select="$input"/>
                                                                                    <xsl:with-param name="pattern" select="'À'"/>
                                                                                    <xsl:with-param name="replacement" select="'&Agrave;'"/>
                                                                                </xsl:call-template>
                                                                                </xsl:with-param>
                                                                                <xsl:with-param name="pattern" select="'Á'"/>
                                                                                <xsl:with-param name="replacement" select="'&Aacute;'"/>
                                                                            </xsl:call-template>
                                                                            </xsl:with-param>
                                                                            <xsl:with-param name="pattern" select="'Â'"/>
                                                                            <xsl:with-param name="replacement" select="'&Acirc;'"/>
                                                                        </xsl:call-template>
                                                                        </xsl:with-param>
                                                                        <xsl:with-param name="pattern" select="'È'"/>
                                                                        <xsl:with-param name="replacement" select="'&Egrave;'"/>
                                                                    </xsl:call-template>
                                                                    </xsl:with-param>
                                                                    <xsl:with-param name="pattern" select="'É'"/>
                                                                    <xsl:with-param name="replacement" select="'&Eacute;'"/>
                                                                </xsl:call-template>
                                                                </xsl:with-param>
                                                                <xsl:with-param name="pattern" select="'Ê'"/>
                                                                <xsl:with-param name="replacement" select="'&Ecirc;'"/>
                                                            </xsl:call-template>
                                                            </xsl:with-param>
                                                            <xsl:with-param name="pattern" select="'Ì'"/>
                                                            <xsl:with-param name="replacement" select="'&Igrave;'"/>
                                                        </xsl:call-template>
                                                        </xsl:with-param>
                                                        <xsl:with-param name="pattern" select="'Í'"/>
                                                        <xsl:with-param name="replacement" select="'&Iacute;'"/>
                                                    </xsl:call-template>
                                                    </xsl:with-param>
                                                    <xsl:with-param name="pattern" select="'Î'"/>
                                                    <xsl:with-param name="replacement" select="'&Icirc;'"/>
                                                </xsl:call-template>
                                                </xsl:with-param>
                                                <xsl:with-param name="pattern" select="'Ò'"/>
                                                <xsl:with-param name="replacement" select="'&Ograve;'"/>
                                            </xsl:call-template>
                                            </xsl:with-param>
                                            <xsl:with-param name="pattern" select="'Ó'"/>
                                            <xsl:with-param name="replacement" select="'&Oacute;'"/>
                                        </xsl:call-template>
                                        </xsl:with-param>
                                        <xsl:with-param name="pattern" select="'Ô'"/>
                                        <xsl:with-param name="replacement" select="'&Ocirc;'"/>
                                    </xsl:call-template>
                                    </xsl:with-param>
                                    <xsl:with-param name="pattern" select="'Ù'"/>
                                    <xsl:with-param name="replacement" select="'&Ugrave;'"/>
                                </xsl:call-template>
                                </xsl:with-param>
                                <xsl:with-param name="pattern" select="'Ú'"/>
                                <xsl:with-param name="replacement" select="'&Uacute;'"/>
                            </xsl:call-template>
                            </xsl:with-param>
                            <xsl:with-param name="pattern" select="'Û'"/>
                            <xsl:with-param name="replacement" select="'&Ucirc;'"/>
                        </xsl:call-template>
                        </xsl:with-param>
                        <xsl:with-param name="pattern" select="'Ý'"/>
                        <xsl:with-param name="replacement" select="'&Yacute;'"/>
                    </xsl:call-template>
                    </xsl:with-param>
                    <xsl:with-param name="pattern" select="'Œ'"/>
                    <xsl:with-param name="replacement" select="'&OElig;'"/>
                </xsl:call-template>
                </xsl:with-param>
                <xsl:with-param name="pattern" select="'Ç'"/>
                <xsl:with-param name="replacement" select="'&Ccedil;'"/>
            </xsl:call-template>
            </xsl:with-param>
            <xsl:with-param name="pattern" select="'&NBSP;'"/>
            <xsl:with-param name="replacement" select="' '"/>
        </xsl:call-template>
        </xsl:with-param>
        <xsl:with-param name="pattern" select="'&SHY;'"/>
        <xsl:with-param name="replacement" select="' '"/>
    </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="$input"/>
    </xsl:otherwise>
    </xsl:choose>
</xsl:template>