You've started on the right lines by defining an identity template rule that copies nodes unchanged by default. Then you just need to add a rule for nodes that match oldname. In XSLT 2.0 you can write:
Code:
<xsl:template match="*[local-name()=$oldname]>
<xsl:element name="$newname">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
Unfortunately Microsoft's XSLT processor doesn't support XSLT 2.0, and XSLT 1.0 doesn't allow variable references in match patterns. As Microsoft's XML technology is now years behind the latest standards you would be better off moving to third-party tools - both Saxon and XmlPrime support the 2.0 standard on .NET. But if you don't want to do that a workaround would be to define a key:
Code:
<xsl:key name="k" match="*[local-name()=$oldname]" use="1"/>
and then use the key in the match pattern:
Code:
<xsl:template match="key('k', 1)">