К слову сказать, с вашей сортировкой меток справится, пожалуй, только рекурсивных перебор оных.
Для этого делаем примерно следующее.
Вверху шаблона, после тега xsl:output добавляем следующее:
<xsl:variable name="keystring" select="'0123456789,АаБбВвГгДдЕеЖжЗзИиЙйКкЛлМмНнОоПпРрСсТтУуФфХхЦцЧчШшЩщЫыЭэЮюЯя,AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz'"/>
<xsl:variable name="delimiter" select="','"/>
Потом находим в шаблоне вызов темплейта tags/tag, вот такой:
<xsl:apply-templates select="tags/tag"/>
и вместо него вставляем следующий код:
<xsl:call-template name="tagging">
<xsl:with-param name="s" select="$keystring"/>
<xsl:with-param name="delimiter" select="$delimiter"/>
</xsl:call-template>
И где-нибудь в конце всего шаблона, перед закрывающим тегом /xsl:stylesheet вставляем вот такой новый темплейт:
<xsl:template name="tagging">
<xsl:param name="s"/>
<xsl:param name="delimiter"/>
<xsl:variable name="a">
<xsl:value-of select="substring($s,1,1)"/>
</xsl:variable>
<xsl:variable name="s0">
<xsl:value-of select="substring-after($s,$a)"/>
</xsl:variable>
<xsl:if test="$s != ''">
<xsl:choose>
<xsl:when test="$a != $delimiter and tags/tag[substring(tag_name,1,1) = $a]/node()">
<xsl:apply-templates select="tags/tag[substring(tag_name,1,1) = $a]"/>
</xsl:when>
<xsl:otherwise>
<xsl:if test="$a = $delimiter"><br/></xsl:if>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="tagging">
<xsl:with-param name="s" select="$s0"/>
<xsl:with-param name="delimiter" select="$delimiter"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
Теперь порядок сортировки ваших тегов определяется строкой, записанной в переменную $keystring в самом начале шаблона, а запятые в этой строке заменяются на теги <br/>, если вам это не нужно то просто уберите запятые из переменной $keystring
Способ немного некрасивый и громоздкий, но я не вижу других вариантов сделать сортировку не отвечающую ни ASC ни DESC.