I am not sure why the stylesheet you show uses XSLT 1.0 since you tagged the question with XSLT 2.0 and tokenize is a 2.0 function.
Also, your expected output contains a typo I think. Perhaps this is what you meant to write:
<student>
<id>1</id>
<name>a</name>
</student>
<student>
<id>2</id>
<name>b</name>
</student>
Why you get an exception
In XSLT, expressions depend heavily on the context. A line like the following:
<xsl:element name="{@name}">
depends on the context in the sense that it retrieves the value of the name
attribute of either the current template match or the current item in an xsl:for-each
.
In your case, the context is this:
<xsl:for-each select="tokenize(.,',')">
So, the context for {@name}
is a tokenized string - that of course does not have any attributes.
Stylesheet
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="xml"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/students">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="field[@name='id']">
<xsl:variable name="match" select="."/>
<xsl:for-each select="tokenize(.,',')">
<xsl:variable name="id-pos" select="position()"/>
<student>
<id>
<xsl:value-of select="."/>
</id>
<name>
<xsl:value-of select="tokenize($match/following-sibling::field[@name='name'],',')[position() = $id-pos]"/>
</name>
</student>
</xsl:for-each>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
Output
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student>
<id>1</id>
<name>a</name>
</student>
<student>
<id>2</id>
<name>b</name>
</student>
<student>
<id>3</id>
<name>c</name>
</student>
</students>