Sorting and Grouping records / Nodes in Biztalk Mapper

Thursday, December 1, 2011

 how easy it is to use custom XSLT inside the BizTalk Mapper to sort data.  Sorting data inside the map can be doing using inline XSLT like this:

<xsl:for-each select="Record">
<xsl:sort select="Id" data-type="number" order="ascending"/>
<xsl:element name="Customers">
<xsl:element name="Id"><xsl:value-of select="Id" /></xsl:element>
</xsl:element>
</xsl:for-each>

Sometimes sorting just is not enough.  What if you also needed to group your data and break it up into single messages?  This can be done several different ways including using xpath, .net components, or something external to BizTalk all together; with none of them really being ideal. 

Another non-ideal way to accomplish grouping and debatching is to use pure BizTalk Messaging!  Yes, pure messaging can group and debatch your data.  Now, it is a little strange and takes a few hops through the message box, but it is a relatively simple solution to implement in a short amount of time.

So, how does it work?

Pass 1 will apply a map on the Receive Port to sort the data.  The Send Port will apply another map to group the data.

The grouping map using two Functoids.  One determines if the current record and the past record have the same Id.  The second does the grouping. 

The code in these Scripting Functoids looks like this:

True / False
string newNode = "";
string pastValue = "X";

public string MakeNewNode(string currentValue)
{
if (pastValue != currentValue)
{
   pastValue = currentValue;
   newNode = "true";
}
else
   newNode = "false";

return newNode;
}

Grouping
<xsl:template name="GroupByID">
<xsl:param name="param1"/>
<xsl:param name="param2"/>
  <xsl:if test="$param1='true'">
    <xsl:element name="Group">
      <xsl:for-each select="//Customers[Id=$param2]">
          <xsl:element name="Customer">
              <xsl:element name="Id"><xsl:value-of select="Id"/></xsl:element>
              <xsl:element name="Name"><xsl:value-of select="Name"/></xsl:element>
          </xsl:element>
      </xsl:for-each>
    </xsl:element>
  </xsl:if>
</xsl:template>

Pass 2 will apply an envelope to split the data inside the Receive Port and publish single messages to the message box.

No comments:

Post a Comment

Post Your Comment...