I have a requirement to gather same "type" and "pin" field values under one field in output when the values are present in both fields else create under seperate field.
this is my input to xslt:
<?xml version='1.0' encoding='UTF-8'?>
<record>
<file>
<type>DI</type>
<pin>123</pin>
</file>
<file>
<type>DI</type>
<pin>123</pin>
</file>
<file>
<type>DI</type>
<pin>456</pin>
</file>
<file>
<type>DI</type>
<pin></pin>
</file>
<file>
<type>DI</type>
<pin></pin>
</file>
<file>
<type>DM</type>
<pin>123</pin>
</file>
<file>
<type>DM</type>
<pin>123</pin>
</file>
<file>
<type>DM</type>
<pin>456</pin>
</file>
<file>
<type>DM</type>
<pin></pin>
</file>
<file>
<type>DM</type>
<pin></pin>
</file>
<file>
<type>CM</type>
<pin>123</pin>
</file>
<file>
<type>CM</type>
<pin>123</pin>
</file>
<file>
<type>CM</type>
<pin>456</pin>
</file>
<file>
<type>CM</type>
<pin></pin>
</file>
<file>
<type>CM</type>
<pin></pin>
</file>
</record>
i want the above payload converted to below expected output
<?xml version='1.0' encoding='UTF-8'?>
<root>
<record>
<cat>
<file>
<type>DI</type>
<pin>123</pin>
</file>
<file>
<type>DI</type>
<pin>123</pin>
</file>
</cat>
<cat>
<file>
<type>DM</type>
<pin>123</pin>
</file>
<file>
<type>DM</type>
<pin>123</pin>
</file>
</cat>
<cat>
<file>
<type>CM</type>
<pin>123</pin>
</file>
<file>
<type>CM</type>
<pin>123</pin>
</file>
</cat>
<cat>
<file>
<type>DI</type>
<pin>456</pin>
</file>
</cat>
<cat>
<file>
<type>DM</type>
<pin>456</pin>
</file>
</cat>
<cat>
<file>
<type>CM</type>
<pin>456</pin>
</file>
</cat>
<cat>
<file>
<type>DI</type>
<pin></pin>
</file>
</cat>
<cat>
<file>
<type>DI</type>
<pin></pin>
</file>
</cat>
<cat>
<file>
<type>DM</type>
<pin></pin>
</file>
</cat>
<cat>
<file>
<type>DM</type>
<pin></pin>
</file>
</cat>
<cat>
<file>
<type>CM</type>
<pin></pin>
</file>
</cat>
<cat>
<file>
<type>CM</type>
<pin></pin>
</file>
</cat>
</record>
</root>
my xslt is not working
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/record">
<root><xsl:for-each-group select="record" group-by="type">
<xsl:choose>
<xsl:for-each-group select="record" group-by="pin">
<xsl:when test="current-grouping-key()">
<cat>
<xsl:copy-of select="current-group()"/>
</cat>
</xsl:when></xsl:for-each-group>
<xsl:otherwise>
<cat>
<xsl:copy-of select="."/>
</cat>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group></root>
</xsl:template>
</xsl:stylesheet>
The xslt should be transformed to generate above output based on incoming payload "type" and "pin". example: In above case, if "type"="DI" then check in incoming xml for where both "type" and "pin" field values are same, then merge them in one target field with same details, but if "type" is available and "pin" value is blank then they should create under separate target field individually. "type" is mandatory field and "pin" is optional field.
I think, if you adapt your code to
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/root">
<root>
<xsl:for-each-group select="record/file" group-by="type">
<xsl:for-each-group select="current-group()" group-by="pin">
<xsl:choose>
<xsl:when test="normalize-space(current-grouping-key())">
<cat>
<xsl:copy-of select="current-group()"/>
</cat>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="current-group()">
<cat>
<xsl:copy-of select="."/>
</cat>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:for-each-group>
</root>
</xsl:template>
</xsl:stylesheet>
your requirement is implemented.