I already talked about Muenchian Grouping in BizTalk Maps in the past:
Inspired by a question in BizTalk Server Forums: XSLT Mapping Question (Summing Values)… I decided to solve this problem and publish this sample to help this user… what can I say… I simply love mapping problems!!!
So how can we perform multi-level Muenchian grouping in BizTalk Maps and perform some mathematical operations on this group?
You can read more about the problem in the thread, nut basically the problem is: To sum all records and create a unique record for records having the same account type and city!
Solution
Add two scripting functoids to the map:
- In the first, configure to an “Inline XSLT Call Template” and put key expression
<xsl:key name="groups" match="Record" use="concat(City, '|', AccountType)"/>
- In the second, configure to an “Inline XSLT” and the rest of the XSL
<xsl:for-each select="Record[generate-id(.)=generate-id(key('groups',concat(City, '|', AccountType)))]"> <Record> <xsl:variable name="city" select="City/text()" /> <xsl:variable name="type" select="AccountType/text()" /> <AccountType> <xsl:value-of select="$type" /> </AccountType> <City> <xsl:value-of select="$city" /> </City> <xsl:variable name="negativeTotal" select="sum(//Record[(City = $city) and (AccountType = $type) and (Sign = '-')]/Price)" /> <xsl:variable name="positiveTotal" select="sum(//Record[(City = $city) and (AccountType = $type) and (Sign = '+')]/Price)" /> <xsl:choose> <xsl:when test="$positiveTotal > $negativeTotal"> <Sign>+</Sign> <Price> <xsl:value-of select="$positiveTotal - $negativeTotal" /> </Price> </xsl:when> <xsl:otherwise> <Sign>-</Sign> <Price> <xsl:value-of select="$negativeTotal - $positiveTotal" /> </Price> </xsl:otherwise> </xsl:choose> </Record> </xsl:for-each>
- Drag a link from the Second Scripting Functoid to the record “Record” in the destination schema;
You can download the source code from:
How to implement multi-level Muenchian grouping in BizTalk Maps
GitHub
Since it seems like most of the map consists of xslt, why would you use the mapper at all? Why not use a pure xslt map?
Hi Erik,
There are several ways to solve a particular mapping problem; in this particular case I could use a pure XSLT map.
So why would I use the mapper at all? I think that in the long term, this way is more readable than using an pure XSLT map
And if it had different records I wouldn’t lose the BizTalk Mapper functionalities.
I normally like to use the best of both worlds: the best of custom XSLT and the best of BizTalk Mapper functionalities. However in some case doing a pure XSLT map makes the map more efficient (performance)
Hi Sandro,
If all elements in your schema have a namespace prefix on it such as “ns0:” , I am unable to get your sample to work. What do you need to do for the “key” and the for-each statement to key this to work.
In many cases, the schemas we have to work contain the namespace prefix for each element.
Hi Sandro,
How does your example work when every element in the sample schema contains the namespace prefix of ns0:
What do we have to change in the Key and for-each statement in order for this to work ?
Hi Sandro,
How do I apply this to 2 schema which has completely different structure ?