The result you show can be produced by using a recursive named template to enumerate the years:
<xsl:template name="enumerate">
<xsl:param name="start"/>
<xsl:param name="end"/>
<xsl:value-of select="$start" />
<xsl:if test="$start < $end">
<xsl:text> </xsl:text>
<xsl:call-template name="enumerate">
<xsl:with-param name="start" select="$start + 1"/>
<xsl:with-param name="end" select="$end"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
In your example you would call the template as:
<xsl:template match="dates">
<xsl:call-template name="enumerate">
<xsl:with-param name="start" select="substring(date[@id=1], 1, 4) + 1"/>
<xsl:with-param name="end" select="substring(date[@id=2], 1, 4)"/>
</xsl:call-template>
</xsl:template>