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 to their proper destination, and for which we implemented the following challenges:
- Concatenate the first and last names in order to give the full name (Concatenation of values).
- Map the Address in its destination element (Direct copy).
- Transform the date of birth into 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 work.
📝 One-Minute Brief
In this second part of the series, Sandro goes “under the hood” of the BizTalk Mapper to prove the target-driven processing model. By intentionally disorganizing a destination schema, he demonstrates how the BizTalk compiler translates graphical links into specific XSLT/XPath segments. The post walks through how the engine traverses the target schema from top to bottom, executing mapping rules only as it encounters elements in the destination, regardless of where they sit in the source.
This way, we obtained the following final map:
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()) , ", " , string(FirstName/text()))" />
<FullName>
<xsl:value-of select="$var:v3" />
</FullName>
- The fifth element is Age, a link is found, which means thatthe 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 contains two elements: TotalInternational and TotalNational, both with associated links.
- 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) , "4")" />
<xsl:variable name="var:v7" select="userCSharp:LogicalEq(string($var:v6) , "+351")" />
<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),"1000")" />
</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 , "4")" />
<xsl:variable name="var:v15" select="userCSharp:LogicalEq(string($var:v14) , "+351")" />
<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),"1000")" />
</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
- How BizTalk Maps Work – Processing model (Part 1)
- How BizTalk Maps Work – The sequence of links (Part 3)
For those looking to move beyond the basics of message transformation, I highly recommend checking out my eBook, BizTalk Mapping Patterns & Best Practices, published in partnership with BizTalk360.
This resource is a deep dive into the real-world challenges of data transformation. It covers:
- Mapping Patterns: From simple field-to-field links to complex structural shifts.
- Performance Optimization: How to build maps that don’t slow down your environment.
- XSLT vs. Functoids: Knowing exactly when to use built-in tools and when to write custom code.
Whether you are maintaining a legacy BizTalk 2010 environment or planning a migration, these patterns are the foundation of clean, maintainable integration.
Download the full eBook here: BizTalk Mapping Patterns & Best Practices
Hope you find this helpful! If you liked the content or found it useful and would like to support me in writing more, consider buying (or helping to buy) a Star Wars Lego set for my son.
