Given the following XML:
11
To do this in XSLT 1.0, you will have to use a technique called "muenchian grouping". First create a key of the nodes on which you wish to group
<xsl:key name="intfield" match="int" use="substring-before(@name, ':')" />
Next, you iterate it through all the nodes, but only selecting the ones that happen to be first in the relevant group
<xsl:for-each select="int[generate-id() = generate-id(key('intfield', substring-before(@name, ':'))[1])]">
Next, you can iterate use the key to iterate over all nodes in the group
<xsl:variable name="intfieldname" select="substring-before(@name, ':')"/>
<xsl:for-each select="key('intfield', $intfieldname)">
Putting this all together gives
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"/>
<xsl:key name="intfield" match="int" use="substring-before(@name, ':')"/>
<xsl:template match="/results">
<results>
<xsl:for-each select="int[generate-id() = generate-id(key('intfield', substring-before(@name, ':'))[1])]">
<xsl:variable name="intfieldname" select="substring-before(@name, ':')"/>
<field>
<xsl:attribute name="name">
<xsl:value-of select="$intfieldname"/>
</xsl:attribute>
<xsl:for-each select="key('intfield', $intfieldname)">
<value>
<xsl:attribute name="name">
<xsl:value-of select="substring-after(@name, ':')"/>
</xsl:attribute>
<xsl:value-of select="."/>
</value>
</xsl:for-each>
</field>
</xsl:for-each>
</results>
</xsl:template>
</xsl:stylesheet>
In your example, 'intfield' becomes 'numberfield' though. I have kept the name as 'intfield' in the above example.
Muenchian grouping is a work of genius. It's not easy to understand, but see: http://www.jenitennison.com/xslt/grouping/muenchian.html
To simplify the process the W3C specifically supported grouping in XSLT2.0. See, for example: http://www.xml.com/pub/a/2003/11/05/tr.html
However not all environments support XSLT2.0