← all checks
warning //xsl:attribute[not(contains(@name, '{')) and not(@_name)][not(@namespace) and not(@_namespace)][parent::*[not(self::xsl:*)]][not(*) or (count(*) = 1 and (xsl:value-of[not(@separator) and not(@_separator)] or xsl:text[not(@disable-output-escaping) and not(@_disable-output-escaping)]))][not(preceding-sibling::*[not(self::xsl:variable) and not(self::xsl:attribute)])][not(preceding-sibling::xsl:attribute[@_name or not(@name) or contains(@name, '{')])][not(preceding-sibling::xsl:attribute/xslint:attribute(., 'name') = xslint:attribute(., 'name'))][not(some $held in ../@*[not(namespace-uri() = 'http://www.w3.org/1999/XSL/Transform')] satisfies local-name($held) = replace(xslint:attribute(., 'name'), '^.*:', ''))][not(@separator) and not(@_separator) and not(@type) and not(@_type) and not(@validation) and not(@_validation)][not(some $value in (. | .//@select | .//@_select) satisfies preceding-sibling::xsl:variable[contains($value, concat('$', xslint:attribute(., 'name')))])]

Not creating attribute correctly

An xsl:attribute with a static name and a simple value writes what a literal attribute writes, and sends its reader looking for a computation that is not there. On a literal result element, when its value is plain text, empty, or a single xsl:value-of or xsl:text, write it in the start tag, with an attribute value template for a computed value and {{ for a literal brace.

Incorrect:

<td>
  <xsl:attribute name="class"><xsl:value-of select="@c"/></xsl:attribute>
  <xsl:attribute name="role">cell</xsl:attribute>
</td>

Correct:

<td class="{@c}" role="cell"/>

It is left alone when it carries namespace, separator, type or validation, reads a variable declared beside it, or follows an instruction that could write an attribute itself.