Это преобразование :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kProdById" match="product" use="productid"/>
<xsl:template match=
"product
[generate-id()
=
generate-id(key('kProdById', productid)[1])
]
">
<xsl:apply-templates
select="key('kProdById', productid)/remarks"/>
</xsl:template>
<xsl:template match="remarks">
<xsl:value-of select=
"concat('Productid : ', ../productid,
' Remark:', title, '
')"/>
</xsl:template>
<xsl:template match="product"/>
</xsl:stylesheet>
при применении к предоставленному документу XML :
<products>
<product>
<productid>1001</productid>
<remarks>
<title>This is remarks text of 1001</title>
</remarks>
</product>
<product>
<productid>1002</productid>
<remarks>
<title>This is remarks text of 1002</title>
</remarks>
</product>
<product>
<productid>1001</productid>
<remarks>
<title>This is remarks text of 1001</title>
</remarks>
</product>
<product>
<productid>1001</productid>
<remarks>
<title>This is another remarks text of 1001</title>
</remarks>
</product>
</products>
дает желаемый, правильный результат :
Productid : 1001 Remark:This is remarks text of 1001
Productid : 1001 Remark:This is remarks text of 1001
Productid : 1001 Remark:This is another remarks text of 1001
Productid : 1002 Remark:This is remarks text of 1002
Пояснение : Использование мюнхенского метода для группировки .