Проблема с этой строкой ...
<xsl:for-each select="//VAR[contains(@NAME, 'VER')]/@VALUE">
Это позволит получить все VAR
элементы с атрибутом имени «VER», тогда как вам нужен только один с тем же префиксом.
Итак, вы можете определить переменную следующим образом:
<xsl:variable name="prefix" select="substring-before(../@NAME, '-TYPE')" />
Тогда ваше выражение становится таким ...
<xsl:for-each select="//VAR[@NAME = concat($prefix, '-VER')]/@VALUE">
Или чуть более эффективно (и, возможно, более надежно, если в вашем XML действительно было несколько элементов FILE
) ...
<xsl:for-each select="../following-sibling::VAR[@NAME = concat($prefix, '-VER')]/@VALUE">
На самом деле, я не думаю, что вам нужно xsl:for-each
здесь, если у вас будет только один "VER" и "LINK" для каждого типа.
Попробуйте этот шаблон вместо
<xsl:template match="/*">
<Worksheet ss:Name="{local-name(/*/*)}">
<Table x:FullColumns="1" x:FullRows="1">
<xsl:for-each select="//FILE">
<Row>
<Cell>
<Data ss:Type="String">
<xsl:value-of select="@EXTNAME"/>
</Data>
</Cell>
</Row>
<xsl:for-each select="VAR[contains(@NAME, 'TYPE')]/@VALUE">
<Row>
<Cell>
<Data ss:Type="String">
<xsl:value-of select="."/>
</Data>
</Cell>
<xsl:variable name="prefix" select="substring-before(../@NAME, '-TYPE')" />
<Cell>
<Data ss:Type="String">
<xsl:value-of select="../following-sibling::VAR[@NAME = concat($prefix, '-VER')]/@VALUE"/>
</Data>
</Cell>
<Cell>
<Data ss:Type="String">
<xsl:value-of select="../following-sibling::VAR[@NAME = concat($prefix, '-LINK')]/@VALUE"/>
</Data>
</Cell>
</Row>
</xsl:for-each>
</xsl:for-each>
</Table>
</Worksheet>
</xsl:template>