Add the rule
<xsl:template match="*[not(@*|*)]">
<xsl:copy-of select="."/>
</xsl:template>
ie if an element has no attributes or element children, copy it unchanged.
Looking at this code:
<xsl:if test="@*">
<xsl:for-each select="@*">
<xsl:element name="{concat(name(..),name())}">
<xsl:value-of select="." />
</xsl:element>
</xsl:for-each>
</xsl:if>
the xsl:if is unnecessary since if there are no attributes the for-each will do nothing.
Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference