XSLT Muenchian Grouping - BizTalk Complex Transformation
Introduction
I have an XML in the following format:
<section>
<entries>
<entry>
<name>Product 1</name>
<categories>
<category>Fruit</category>
<category>Apple</category>
<category>Green</category>
</categories>
</entry>
<entry>
<name>Product 2</name>
<categories>
<category>Fruit</category>
<category>Apple</category>
<category>Red</category>
</categories>
</entry>
<entry>
<name>Product 3</name>
<categories>
<category>Fruit</category>
<category>Apple</category>
<category>Blue</category>
</categories>
</entry>
<entry>
<name>Product 4</name>
<categories>
<category>Fruit</category>
<category>Apple</category>
<category>Black</category>
</categories>
</entry>
<entry>
<name>Product 5</name>
<categories>
<category>Fruit</category>
<category>Apple</category>
<category>Purple</category>
</categories>
</entry>
</entries>
</section>
I want to convert this XML into another format of the following type:
<categories>
<category>
<categoryname>Fruit</categoryname>
<products>
<product>Product 1</product>
<product>Product 2</product>
<product>Product 3</product>
<product>Product 4</product>
<product>Product 5</product>
</products>
</category>
<category>
<categoryname>Apple</categoryname>
<products>
<product>Product 1</product>
<product>Product 2</product>
<product>Product 3</product>
<product>Product 4</product>
<product>Product 5</product>
</products>
</category>
<category>
<categoryname>Green</categoryname>
<products>
<product>Product 1</product>
</products>
</category>
<category>
<categoryname>Red</categoryname>
<products>
<product>Product 2</product>
</products>
</category>
<category>
<categoryname>Blue</categoryname>
<products>
<product>Product 3</product>
</products>
</category>
<category>
<categoryname>Black</categoryname>
<products>
<product>Product 4</product>
</products>
</category>
<category>
<categoryname>Purple</categoryname>
<products>
<product>Product 5</product>
</products>
</category>
</categories>
Building the Sample
Custom XSLT is required in BizTalk Map for such type of format conversion.
First create Schema for Input and OutPut Xml.
Custom XSLT will convert this kind of format :
Within the XSLT, we will use a method called the Muenchian Method to handle the grouping.
Just below the <xsl:output> block of our XSLT, we're going to create a key value for this grouping. This creates an index which the transform engine can use to loop through each unique value of that key.
<xsl:key name="groups" match="entries/entry/categories/category/text()" use="."/>
From there, at the top of where we're going to start our /Category branch, we can modify the "for-each" block to loop through our key instead of source nodes, like we might typically do.
<xsl:for-each select="entries/entry/categories/category/text()[generate-id()=generate-id(key('groups',.))]">
Finally we loop through the "groups" key we created before and output our data:
<xsl:for-each select="key('groups',.)">
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var" exclude-result-prefixes="msxsl var" version="1.0">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
<xsl:key name="groups" match="entries/entry/categories/category/text()" use="."/>
<xsl:template match="/">
<xsl:apply-templates select="/section" />
</xsl:template>
<xsl:template match="/section">
<categories>
<xsl:for-each select="entries/entry/categories/category/text()[generate-id()=generate-id(key('groups',.))]">
<category>
<categoryname>
<xsl:value-of select="." />
</categoryname>
<products>
<xsl:for-each select="key('groups',.)">
<product>
<xsl:value-of select="../../../name/text()" />
</product>
</xsl:for-each>
</products>
</category >
</xsl:for-each>
</categories>
</xsl:template>
</xsl:stylesheet>
See Also
Read suggested related topics:
- BizTalk Server: Grouping and Sorting Operations Inside BizTalk Maps Using the Muenchian Method
- BizTalk Virtual Mapper VS Custom-XSLT article to see benefits of using XSLT vs. the BizTalk Mapper.
- BizTalk Server 2010: Grouping and Debatching/Splitting Inbound Messages (TypedPolled) from WCF-SQL Adapter
- BizTalk Server: Basics principles of Maps
- BizTalk Server: How Maps Work
- BizTalk Server 2010: Mapper
- Muenchian Grouping and Sorting in BizTalk Maps by Chris Romp
Good place to find an extensive amount of BizTalk related articles is the TechNet Wiki itself. The best entry point is BizTalk Server Resources on the TechNet Wiki.