How BizTalk Maps Work – Deconstructing a map (Part 2)

Posted: April 27, 2012  |  Categories: BizTalk Maps

In this article, we will use the basic mapping operations previously described, and analyze the decisions taken by the BizTalk mapping engine.

Basically, on this mapping problem, there are two similar schemes, which we intend to map the source elements in their proper destination and for which we implemented the following challenges:

  • Concatenate the first and last name in order to give the full name (Concatenation of values);
  • Map the Address in its destination element (Direct copy)
  • Transform the date of birth in age (Custom scripts);
  • The Zip Code should only be mapped if it has a valid string, otherwise, it will not be mapped (Conditional selection);
  • The element Civil Status is optional and as we have no evidence in the source to map it, it should be ignored (Add new values).
  • Additionally, we perform a more advanced mapping logic to calculate the total of national and international calls using cycles, conditional selections, and mathematical operations.

As you can see, we intentionally switched the order of elements in the destination schema in order to, more easily, understand and verify how BizTalk maps works.

This way we obtained the following final map:

How Maps Work final result

Note: The order in which we perform the links between the elements from source to destination schema, in this scenario, is irrelevant to the compiler, however the same cannot be said for functoids. The functoids require certain input parameters that can vary according to the functoid that we are using, in this case, the order with which we associate the link is extremely important

The previous image of the map is actually the following representation of this XSLT document:

Based on this document we will follow the behavior of the compiler. What he performs is to translate the links on the map, as he finds them, while he traverses the destination schema from beginning to end:

  • The first element found is “Address”; Since there is a link associated with this element, the link is translated by one XPath expression (”Address/text()”) that defines the element to be extracted from the source:
<Address>
   <xsl:value-of select="Address/text()" />
</Address>
  • The second element found is “ZipCode” also with a link associated; It is a conditional selection that will be translated into an XSLT condition (xsl:if):
<xsl:variable name="var:v1" select="userCSharp:LogicalExistence(boolean(ZipCode))" />
<xsl:if test="string($var:v1)='true'">
   <xsl:variable name="var:v2" select="ZipCode/text()" />
   <ZipCode>
      <xsl:value-of select="$var:v2" />
   </ZipCode>
</xsl:if>
  • The third element is “CivilStatus” since there are no links associated with this element, it is ignored in the mapping process.
  • The fourth element to be processed is “FullName” and once again there is a link associated, which corresponds to the concatenation of two elements of the origin; If you check the generated code, is assigned to the element “FullName” the value of variable “$var:v3” that is generated from the execution of the function userCSharp:StringConcat that visually represents the String Concatenate Functoid:
<xsl:variable name="var:v3" select="userCSharp:StringConcat(string(LastName/text()) , &quot;, &quot; , string(FirstName/text()))" />
<FullName>
   <xsl:value-of select="$var:v3" />
</FullName>
  • The fifth element is “Age”, a link is found which means that custom script found inside the CSharp Inline Scripting Functoid will be carried out:
<xsl:variable name="var:v4" select="userCSharp:CalculateMyAge(string(DateOfBirth/text()))" />
<Age>
   <xsl:value-of select="$var:v4" />
</Age>
  • Finally, we found the record “PhoneBilling” that contain two elements: “TotalInternational” and “TotalNational” both with links associated.
    • Note that although we have not defined any cycle through loop functoid, the compiler is smart enough to realize that we are dealing with a cycle and translate it correctly.
    • However, unfortunately, it will create its own cycle for each element. For better optimization, it will require us to use a custom script.
    • Both elements are calculated using conditions and mathematical calculations as you will see in the generated code
<PhoneBilling>
   <xsl:variable name="var:v5" select="userCSharp:InitCumulativeSum(0)" />
   <xsl:for-each select="/s0:PersonOrigin/PhoneCalls">
      <xsl:variable name="var:v6" select="userCSharp:StringLeft(string(@PhoneNumber) , &quot;4&quot;)" />
      <xsl:variable name="var:v7" select="userCSharp:LogicalEq(string($var:v6) , &quot;+351&quot;)" />
      <xsl:variable name="var:v8" select="userCSharp:LogicalNot(string($var:v7))" />
      <xsl:if test="string($var:v8)='true'">
         <xsl:variable name="var:v9" select="@Cost" />
         <xsl:variable name="var:v10" select="userCSharp:AddToCumulativeSum(0,string($var:v9),&quot;1000&quot;)" />
      </xsl:if>
   </xsl:for-each>
   <xsl:variable name="var:v11" select="userCSharp:GetCumulativeSum(0)" />
   <TotalInternational>
      <xsl:value-of select="$var:v11" />
   </TotalInternational>

   <xsl:variable name="var:v12" select="userCSharp:InitCumulativeSum(1)" />
   <xsl:for-each select="/s0:PersonOrigin/PhoneCalls">
      <xsl:variable name="var:v13" select="string(@PhoneNumber)" />
      <xsl:variable name="var:v14" select="userCSharp:StringLeft($var:v13 , &quot;4&quot;)" />
      <xsl:variable name="var:v15" select="userCSharp:LogicalEq(string($var:v14) , &quot;+351&quot;)" />
      <xsl:if test="string($var:v15)='true'">
         <xsl:variable name="var:v16" select="@Cost" />
         <xsl:variable name="var:v17" select="userCSharp:AddToCumulativeSum(1,string($var:v16),&quot;1000&quot;)" />
      </xsl:if>
   </xsl:for-each>
   <xsl:variable name="var:v18" select="userCSharp:GetCumulativeSum(1)" />
   <TotalNational>
      <xsl:value-of select="$var:v18" />
   </TotalNational>
</PhoneBilling>

Related links

Author: Sandro Pereira

Sandro Pereira lives in Portugal and works as a consultant at DevScope. In the past years, he has been working on implementing Integration scenarios both on-premises and cloud for various clients, each with different scenarios from a technical point of view, size, and criticality, using Microsoft Azure, Microsoft BizTalk Server and different technologies like AS2, EDI, RosettaNet, SAP, TIBCO etc. He is a regular blogger, international speaker, and technical reviewer of several BizTalk books all focused on Integration. He is also the author of the book “BizTalk Mapping Patterns & Best Practices”. He has been awarded MVP since 2011 for his contributions to the integration community.

Leave a Reply

Your email address will not be published. Required fields are marked *

turbo360

Back to Top