You would have to work out the 'luminance' value of the RGB background colour and then take a threshold on that to determine if the foreground colour needs to be black or white (for best contrast).
Unfortunately, XSLT (and XPath) don't provide any functions that deal with colours - and seeing as you're stuck with XSLT 1.0 (I'm assuming - because you're using it in browser?) things get a little verbose... but still possible...
Try something like this...
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html"/>
<xsl:variable name="vHexDigits" select="'0123456789abcdef'"/>
<xsl:template match="greetings">
<html>
<body>
<xsl:apply-templates select="greeting"/>
</body>
</html>
</xsl:template>
<xsl:template match="greeting">
<xsl:variable name="vLuminance">
<xsl:call-template name="RGB2Luminance">
<xsl:with-param name="pRed" select="(string-length(substring-before($vHexDigits, substring(@backcolor,1,1))) * 16) + string-length(substring-before($vHexDigits, substring(@backcolor,2,1)))"/>
<xsl:with-param name="pGreen" select="(string-length(substring-before($vHexDigits, substring(@backcolor,3,1))) * 16) + string-length(substring-before($vHexDigits, substring(@backcolor,4,1)))"/>
<xsl:with-param name="pBlue" select="(string-length(substring-before($vHexDigits, substring(@backcolor,5,1))) * 16) + string-length(substring-before($vHexDigits, substring(@backcolor,6,1)))"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="vForegroundColor">
<xsl:choose>
<!-- assume our black/white forground threshold is 0.5 -->
<xsl:when test="$vLuminance > 0.5">
<xsl:text>black</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>white</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<h1>
<span style="background-color: {@backcolor}; color: {$vForegroundColor};">
<xsl:value-of select="."/>
</span>
</h1>
</xsl:template>
<xsl:template name="RGB2Luminance">
<xsl:param name="pRed"/>
<xsl:param name="pGreen"/>
<xsl:param name="pBlue"/>
<xsl:variable name="vR" select="$pRed div 255"/>
<xsl:variable name="vG" select="$pGreen div 255"/>
<xsl:variable name="vB" select="$pBlue div 255"/>
<xsl:variable name="vMax">
<xsl:choose>
<xsl:when test="$vR >= $vG and $vR >= $vB">
<xsl:value-of select="$vR"/>
</xsl:when>
<xsl:when test="$vG >= $vR and $vG >= $vB">
<xsl:value-of select="$vG"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$vB"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="vMin">
<xsl:choose>
<xsl:when test="$vR <= $vG and $vR <= $vB">
<xsl:value-of select="$vR"/>
</xsl:when>
<xsl:when test="$vG <= $vR and $vG <= $vB">
<xsl:value-of select="$vG"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$vB"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="($vMax + $vMin) div 2"/>
</xsl:template>
</xsl:stylesheet>