You can use xsl:for-each-group
and group by field1
and field2
.
Example...
XML Input
<root>
<row>
<field1>2014-04-01</field1>
<field2>AAA123</field2>
<field3>text1</field3>
<field4>text1</field4>
<field5>text1</field5>
</row>
<row>
<field1>2014-04-01</field1>
<field2>AAA123</field2>
<field3>text2</field3>
<field4>text2</field4>
<field5>text2</field5>
</row>
<row>
<field1>2014-04-01</field1>
<field2>BBB456</field2>
<field3>text3</field3>
<field4>text3</field4>
<field5>text3</field5>
</row>
</root>
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<output>
<xsl:for-each-group select="row" group-by="concat(field1,'|',field2)">
<common>
<xsl:apply-templates select="field1,field2"/>
<xsl:apply-templates select="current-group()"/>
</common>
</xsl:for-each-group>
</output>
</xsl:template>
<xsl:template match="row">
<attributes>
<xsl:apply-templates select="*[not(self::field1) and not(self::field2)]"/>
</attributes>
</xsl:template>
</xsl:stylesheet>
XML Output
<output>
<common>
<field1>2014-04-01</field1>
<field2>AAA123</field2>
<attributes>
<field3>text1</field3>
<field4>text1</field4>
<field5>text1</field5>
</attributes>
<attributes>
<field3>text2</field3>
<field4>text2</field4>
<field5>text2</field5>
</attributes>
</common>
<common>
<field1>2014-04-01</field1>
<field2>BBB456</field2>
<attributes>
<field3>text3</field3>
<field4>text3</field4>
<field5>text3</field5>
</attributes>
</common>
</output>