Below is a template to convert richtext that has been encoded and stored in a database to XHTML. This has been extracted from a larger transform used on a project which passed richtext fields as strings within an element. The xslt then transformed those nodes into XHTML.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="no" encoding="utf-8" />
<xsl:template match="RichTextNode">
<!-- store in tmp variable and emit below with escaping disabled -->
<xsl:variable name="tmp">
<xsl:call-template name="xhtml-decode">
<xsl:with-param name="text" select="." />
</xsl:call-template>
</xsl:variable>
<xsl:value-of disable-output-escaping="yes" select="$tmp" />
</xsl:template>
<!-- Replace encoded < > & " ' with unencoded versions for output -->
<!-- Note: replacement is order dependent -->
<xsl:template name="xhtml-decode">
<xsl:param name="text" />
<xsl:variable name="tmp">
<xsl:call-template name="replace-substring">
<xsl:with-param name="to" select="'&'" />
<xsl:with-param name="from" select="'&'" />
<xsl:with-param name="value">
<xsl:call-template name="replace-substring">
<xsl:with-param name="to" select="concat('&','apos;')" />
<xsl:with-param name="from" select="'''" />
<xsl:with-param name="value">
<xsl:call-template name="replace-substring">
<xsl:with-param name="to" select="'"'" />
<xsl:with-param name="from" select="'"'" />
<xsl:with-param name="value">
<xsl:call-template name="replace-substring">
<xsl:with-param name="to" select="'<'" />
<xsl:with-param name="from" select="'<'" />
<xsl:with-param name="value">
<xsl:call-template name="replace-substring">
<xsl:with-param name="to" select="'>'" />
<xsl:with-param name="from" select="'>'" />
<xsl:with-param name="value" select="$text" />
</xsl:call-template>
</xsl:with-param>
</xsl:call-template>
</xsl:with-param>
</xsl:call-template>
</xsl:with-param>
</xsl:call-template>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$tmp" />
</xsl:template>
<xsl:template name="replace-substring">
<xsl:param name="value" />
<xsl:param name="from" />
<xsl:param name="to" />
<xsl:choose>
<xsl:when test="contains($value,$from)">
<xsl:value-of select="substring-before($value,$from)" />
<xsl:value-of select="$to" />
<xsl:call-template name="replace-substring">
<xsl:with-param name="value" select="substring-after($value,$from)" />
<xsl:with-param name="from" select="$from" />
<xsl:with-param name="to" select="$to" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$value" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>