If your element has 10 existing attributes then you're calling this template 10 times, and adding the category element 10 times, and then relying on the duplicates being eliminated. That's a bit of a roundabout way of doing it. If there are no existing attributes, your code won't be invoked at all. Also "<xsl:for-each select=".">" is a no-op.
Do the processing at the element level:
<xsl:template match="catalog">
<...>
<xsl:copy-of select="@*"/>
<xsl:attribute name="category">zzzz</xsl:attribute>
</...>
</xsl:template>
Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference