flat2 deep xslt logic
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<!-- Match the root element of the input document -->
<xsl:template match="ORDERLIST">
<Orders>
<!-- Group the ITEM elements by ID -->
<xsl:for-each select="ITEM[count(. | key('itemsById', ID)[1]) = 1]">
<Order>
<OrderId><xsl:value-of select="ID"/></OrderId>
<!-- Get all PRODUCT elements with the same ID -->
<xsl:for-each select="key('itemsById', ID)">
<Product><xsl:value-of select="PRODUCT"/></Product>
</xsl:for-each>
</Order>
</xsl:for-each>
</Orders>
</xsl:template>
<!-- Define a key to group ITEM elements by ID -->
<xsl:key name="itemsById" match="ITEM" use="ID"/>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<ORDERLIST>
<ITEM>
<ID>870</ID>
<PRODUCT>ABC</PRODUCT>
</ITEM>
<ITEM>
<ID>870</ID>
<PRODUCT>BCD</PRODUCT>
</ITEM>
<ITEM>
<ID>870</ID>
<PRODUCT>DEF</PRODUCT>
</ITEM>
<ITEM>
<ID>800</ID>
<PRODUCT>ABC1</PRODUCT>
</ITEM>
<ITEM>
<ID>800</ID>
<PRODUCT>XYZ1</PRODUCT>
</ITEM>
</ORDERLIST>
<?xml version="1.0" encoding="UTF-8"?>
<Orders>
<Order>
<OrderId>870</OrderId>
<Product>ABC</Product>
<Product>BCD</Product>
<Product>DEF</Product>
</Order>
<OrderId>870</OrderId>
<Product>ABC1</Product>
<Product>XYZ1</Product>
</Order>
</Orders>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<!-- Match the root element of the input document -->
<xsl:template match="ORDERLIST">
<Orders>
<!-- Group the ITEM elements by ID -->
<xsl:for-each select="ITEM">
<xsl:if test="position() = 1 or ID != preceding-sibling::ITEM[1]/ID">
<Order>
<OrderId><xsl:value-of select="ID"/></OrderId>
<xsl:for-each select=". | following-sibling::ITEM[ID=current()/ID]">
<Product><xsl:value-of select="PRODUCT"/></Product>
</xsl:for-each>
</Order>
</xsl:if>
</xsl:for-each>
</Orders>
</xsl:template>
</xsl:stylesheet>
-----------
Explanation:
The XSLT matches the root element of the input document, which is ORDERLIST.
It creates a new Orders element as the root element of the output document.
It loops through each ITEM element and checks if it's the first ITEM element with a given ID value. If it is, it creates a new Order element with that ID value.
For each ITEM element with the same ID value as the first ITEM element, it adds a Product element to the Order element with the value of the PRODUCT element of that ITEM.
The XSLT outputs the transformed XML document with the Orders element as the root element.