Exchanging or routing messages between existing applications, systems, or external partners is one of the many common scenarios in Enterprise integration solutions. And sometimes they are built based on the same data model; however, because they are built in different systems and teams, they can have slight differences, like the order of the elements, the name of the elements, the structure, or even the namespace. As a result of that, we need to be able to transform the original message to the expected message by those systems.
BizTalk Mapper provides you with just-in-time assistance through a shortcut menu when you create links between two record elements of source and destination schemas:
- You can create multiple links simultaneously if:
- Relevant schema structures must be the same where node names are different, but the order is the same or similar.
- Or Record, elements, or field names must match.
- You can manually create single links by dragging and dropping the source element to the destination element if the destination schema doesn’t have similar structures or the same names.
- Or you can use Mass Copy Functoid to copy the element in the input instance message to a destination schema that uses the <any> Element (some kind of generic schema). This functoid also copies any and all of its substructure, and it will re-create it in the output instance message at the linked node in the destination schema.
The BizTalk Mapper provides you with just-in-time assistance through a shortcut menu when you create links between two record elements of source and destination schemas.
📝 One-Minute Brief
This post explores how to simplify complex mappings in BizTalk Server using the Mapper’s automatic linking features. It covers three primary techniques: Link by Name (for matching elements with identical names), Link by Structure (for matching hierarchical structures regardless of names), and Mass Copy (for generic schemas). Additionally, it provides a advanced workaround using Inline XSLT to perform a “Mass Copy” without carrying over unwanted source namespaces into the destination message.
So to accomplish that, open your map and:
- Drag-and-drop the root name of the source schema, in this case, PurchaseOrder, to the root name of the destination schema, which will be, in this case, PO, and release the mouse button.
- A window’s assistance will pop up where you can select create record-to-record links automatically in the following ways:
- Direct Link: Using this technique, the BizTalk Mapper links the record from the source schema to the selected record in the destination schema. This will not copy any kind of hierarchy structure from the source to the destination; it will only link the record or node.
- Link by Structure: Using this technique, the BizTalk Mapper attempts to match the Record and Field nodes within the Record nodes being linked according to the structures of those Record nodes, regardless of the names of the corresponding nodes within those structures.
- Link By Name: Using this technique, the BizTalk Mapper attempts to match the Record and Field nodes within the Record nodes being linked according to the names of the corresponding nodes, regardless of their structure, within the Record nodes being linked.
- Mass Copy: The Mass Copy functoid enables your maps to use schemas that include any and anyAttribute elements. For information about the functoids available in BizTalk Mapper.
Our scenario will have a Purchase Order that will need to be mapped to 3 different systems with 3 different target schemas.
- System A has a similar schema to our system, with the same structure and the same names, but they are presented in a different order.
- Because the destination schema has the same names as the source schema, the best approach in this scenario is to use the Link By Name option.
- System B also has a similar schema to our system; we have the same order and the same schema structure, but the elements have different names.
- Because the destination schema has the structure of the source schema, the best approach in this scenario is to use the Link By Structure option
- The System C has a canonical schema (or generic schema) that will accept any structure.
- Because the destination schema will accept any kind of structure, the best approach in this scenario is to use the Mass Copy option
Scenario A: How to link the record elements by name
To accomplish that, we need:
- Drag the mouse from the root name PurchaseOrder in the source schema, and then drop it to the root name PO in the destination schema.
- On the shortcut menu, click the Link by Name option. The BizTalk Mapper will attempt to match all the Record, Elements, and Field nodes under the PurchaseOrder node according to their names, regardless of their structure, within the node PO.
And the BizTalk Mapper will automatically map all the elements from the source schema to the target schema that have the same name, as the picture below will show:
Of course, this technique has some limitations; the elements need to have the exact same name, and it will only work in some scenarios.
Scenario B: How to link the record elements by structure
To accomplish that, we need:
- Drag the mouse from the root name PurchaseOrder in the source schema, and then drop it to the root name ExternalPO in the destination schema.
- On the shortcut menu, click the Link by Structure option. The BizTalk Mapper will attempt to match all the Record, Elements, and Field nodes under the PurchaseOrder node according to the structure of those elements, regardless of the names of the corresponding nodes within those structures, within the node ExternalPO.
And the BizTalk Mapper will automatically map all the elements from the source schema to the target schema that have the same structure, as the picture below will show:
Again, this technique has the same limitations as the previous one.
Scenario C: How to link using a mass copy functoid
To accomplish tha,t we need:
- Drag-and-drop the Mass Copy functoid from the Toolbox to the map grid page and then:
- Link the source root name PurchaseOrder as an input parameter for the Mass Copy functoid.
- Link the Mass Copy functoid to the destination root name CanonicalPurchaseOrder to set the output parameter from the Mass Copy functoid.
The only problem in using the Mass Copy functoid is that it will move all the elements and values from the source schema to the destination schema, but it will also include the targetNamespace of the source schema in the destination schema, and this behavior can be a problem in some scenarios.
An example of the map output:
<ns0:CanonicalPurchaseOrder xmlns:ns0="http://BizTalkMapperSemanticTranslatorPattern.CanonicalPurchaseOrder">
<From xmlns:ns0="http://BizTalkMapperSemanticTranslatorPattern.PurchaseOrder">From_0</From>
<To xmlns:ns0="http://BizTalkMapperSemanticTranslatorPattern.PurchaseOrder">To_0</To>
<LineItems xmlns:ns0="http://BizTalkMapperSemanticTranslatorPattern.PurchaseOrder">
<Item>
<Product>Product_0</Product>
<Description>Description_0</Description>
<Price>10</Price>
<Quantity>10</Quantity>
</Item>
</LineItems>
</ns0:CanonicalPurchaseOrder>
So how can we avoid this behavior?
However, sometimes the destination schema expects a different message, without the namespaces in the element:
<CanonicalPurchaseOrder xmlns:ns0="http://BizTalkMapperSemanticTranslatorPattern.CanonicalPurchaseOrder">
<From>From_0</From>
<To>To_0</To>
<LineItems>
<Items>
<Product>Product_0</Product>
<Description>Description_0</Description>
<Price>10</Price>
<Quantity>10</Quantity>
</Items>
</LineItems>
</CanonicalPurchaseOrder>
I already saw this scenario many times. So how can we accomplish this?
There is no easy way to accomplish this without the need to use custom XSLT, and you will need to customize the syntax to your scenario.
In this sample, if we need to map everything without namespaces, we need to “replace” the Mass Copy functoid with a Scripting functoid:
- Drag-and-drop the Scripting functoid from the Toolbox to the map grid page and then:
- And link the Scripting functoid to the destination root name CanonicalPurchaseOrder to set the output parameter from the Scripting functoid.
- This functoid will not have any input parameters.
- Double-click on the Scripting functoid to show the Properties window, then:
- Select the Script Functoid Configure tab, and then choose Inline XSLT as your selected script type
- In the Inline script text box, enter the following XSLT code without the comments (they are only for explaining the operation of the script):
<CanonicalPurchaseOrder>
<xsl:for-each select="/s0:PurchaseOrder/*">
<xsl:if test="local-name()!='LineItems'">
<xsl:element name="{local-name(.)}">
<xsl:value-of select="." />
</xsl:element>
</xsl:if>
</xsl:for-each>
<xsl:choose>
<xsl:when test="count(/s0:PurchaseOrder/LineItems) &gt; 0">
<LineItems>
<xsl:for-each select="/s0:PurchaseOrder/LineItems/*">
<Items>
<xsl:for-each select="./*">
<xsl:element name="{local-name(.)}">
<xsl:value-of select="." />
</xsl:element>
</xsl:for-each>
</Items>
</xsl:for-each>
</LineItems>
</xsl:when>
</xsl:choose>
</CanonicalPurchaseOrder>
Basically, what we are doing is:
- The Scripting functoid will not add the root name, so we need to manually add it
- There we are getting all the elements inside PurchaseOrder, but because we need to travel all the elements inside the LineItems, we need to treat this differently, so we will get all the elements except the LineItems.
- The next step is to check if there are LineItems.
- If exist we will travel all the elements inside the LineItems (for each).
- Because the LineItems only contains one record, we will add this manually, but we need an additional cycle this time to travel all the elements inside the record Item.
And with that, we create our own custom Mass copy Functoid.
Download
You can download the source code from GitHub:
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.




I’ve read a couple of places (including a BizTalk book) that you should be able to “override” a mass-copy on a field by field basis by simply linking a functoid to the field to be overridden. “Example a field need to be passed a current date, then have the Date functoid placed a link to destination field this will override mass copy. ” This does not seem to work and generates a warning from the mapper on validation. It doesn’t make sense to me that this should work. Am I missing something?
Want to understand when on directlinks sometimes from the xslt page I can see that foreach is added if it unbounded node and sometimes it is not adding foreach for the node. why this ambiguity or is it any scenario based