 <p>To dynamically create an attribute based on certain conditions, re-jig your code to this...</p> <pre><code>&lt;xsl:element name="{if (@role='rowhead' ) then 'th' else 'td'}"&gt; &lt;xsl:if test="fn:exists(@def)"&gt; &lt;xsl:attribute name="class" select="concat('def-', @def)"/&gt; &lt;/xsl:if&gt; &lt;xsl:apply-templates /&gt; &lt;/xsl:element&gt; </code></pre> <p>If you use <code>xsl:attribute</code> immediately after <code>xsl:element</code> the attribute gets appended on to the element. Note that attributes must be created before any child elements.</p>