Posts Tagged ‘Training’

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 build base on the same data model, however because they are built in different systems and teams they can have slight small 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 transformed the original message to the expect message by that 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 (node names are different but 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 don’t have a 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 use the <any> Element (some kind of generic schema). This functoid also copies any and all of its substructure, and re-creates 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.

So for 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 direct button of the mouse.

just-in-time-assistance-BizTalk-Mapper

  • A windows assistance will pop up were 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 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 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.

  • The System A have a similar schema of our system, with the same structure and the same names, but they are presented in a different order;
    • Because the destination schema have the same names of the source schema, the best approach in this scenario is to use the Link By Name option
  • The System B have also a similar schema of our system, we as the same order and the same schema structure, however the elements have different names;
    • Because the destination schema have the structure of the source schema, the best approach in this scenario is to use the Link By Structure option
  • The System C have 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 accomplished that we need:

  • Drag the mouse from the root name “PurchaseOrder” in the source schema, and then drop it to root name “PO” in the destination schema.
  • On the shortcut menu, click “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 bellow will show:

Link-by-Name

Of course this technique as some limitations, the elements need to have the exact same name, and will only work in some scenarios.

Scenario B: How to link the record elements by structure

To accomplished that we need:

  • Drag the mouse from the root name “PurchaseOrder” in the source schema, and then drop it to root name “ExternalPO” in the destination schema.
  • On the shortcut menu, click “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 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 bellow will show:

Link-by-Structure

Again this technique have the same limitations of the previous one.

Scenario C: How to link using a mass copy functoid

To accomplished that 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 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;

Mass-Copy

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 also will include the targetNamespace of source schema in the destination schema and this behavior can be a problem in some scenarios.

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 expect 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 accomplished 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 for 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 in 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
  • The we are Getting all the element inside “PurchaseOrder” but because we need to travel all the elements inside the LineItems we need to treat this different, so we will get all the element except the ” LineItems”
  • The next step is check if there is “LineItems”
  • If exist we will travel all the element inside the LineItems (for each)
  • Because the “LineItems” only contain 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

The sample code is available for download in Code Gallery:.

Automatically Link The Record Elements By Structure, Name or Using Mass Copy (148.5 KB)
Microsoft Code Gallery

We are getting close to the end of another year and this is the right time to do a personal end-of-year review and make some work/life balance. To do some of your own personal planning for the year ahead. What personal goals do you want to achieve over the next 12 months? But also to look back and reflect on what you achieved in this last year. So in the following of one of my previous posts, this is the list of my contributions in the last six months on MSDN Code Gallery and TechNet Gallery.

MSDN Code Gallery is your destination for downloading sample applications and code snippets, as well as sharing your own resources.

List of contributions on MSDN Code Gallery:

TechNet Gallery is your destination for finding resources written in VB Script, PowerShell, SQL, JavaScript, or other script languages, or other kind of resources (docs, Visio file and so on).

List of contributions on TechNet Gallery:

  • BizTalk Infrastructure and Solution Overview Samples: Creating documentation is boring and it can be a challenging task. However documentation is an important part on every BizTalk Integration projects or for infrastructures operations management and administration. They will help you in many critical situation and will reduce the time needed to carry out different procedures like finding were the machines are hosted, how many machines your environment have, what are the actors (systems, protocols) in a given solution and so on. This contribution is a list of diagrams samples that you can use in your documentation describing Infrastructure, Solution and Technical overview of your BizTalk Solution/Environment.
  • Monitoring Windows Updates and Pending Restarts on the servers using PowerShell: The script will monitor all the servers with Windows Updates ready to be installed, Windows Updates configured to be checked manually or servers that required a reboot. Servers that do not fall under these conditions will not be listed.
  • PowerShell to Configure BizTalk Server Host and Host Instances: One of the task that we need to do in all our new BizTalk environment over and over again is creating and configuring the Host, Host Instances and of course the adapter handlers. This PowerShell script will help you to automate this process according to some of the Best Practices.
  • Collection of Visio 2013 Stencil for BizTalk Server: New version of Visio 2013 Stencil for BizTalk Server with several modern flat Visio 2013 shapes for representing BizTalk Server physical architectures, Integration architectures or solutions diagrams in Visio 2013.
  • Collection of Visio 2010 Stencil for BizTalk Server: New version of Visio 2010 Stencil for BizTalk Server with several modern flat Visio shapes for representing BizTalk Server physical architectures, Integration architectures or solutions diagrams in Visio 2010.
  • Enable all the required IIS features for BizTalk Server with PowerShell: Microsoft Internet Information Services (IIS) provides a Web application infrastructure for many BizTalk Server features. BizTalk Server requires IIS for the following features: HTTP adapter, SOAP adapter, Windows SharePoint Services adapter, Secure Sockets Layer (SSL) encryption and BAM Portal. This PowerShell script to help you automate the process of configuring IIS with all the required features for BizTalk Server.

In the past I developer a demo on “How to Call Orchestration from another project or from another BizTalk Application” that you can read here and download the source code from Code Gallery here.

This demo was compose by one Visual Studio Solution with two different projects:

  • Project1
    • Orch1
    • Schema1
  • Project2
    • Orch2

However there were a few questions about how we can accomplished that using two different solutions… well is the exact same process, but to help clarify this topic and to better help the community members that placed the questions I decide to create a different demo.

In this demo we will create two Visual Studio Solution:

  • CallExternalOrchestrationCommonSolution with a common orchestration that will be called from others orchestrations
    • This will be deployed to a BizTalk Application called “CallExternalOrchestration.Common
  • CallExternalOrchestrationMainSolution with a main Orchestration that will call the common Orchestration using the “Call Orchestration” shape.
    • This will be deployed to a BizTalk Application called “CallExternalOrchestration

In both of the solution I will describe the basic steeps (or the most important steeps) to accomplished

Creating the Common Solution: CallExternalOrchestrationCommonSolution

This project contain an orchestration that will receive two input string (however you can define other types of input like message or other types) and will construct a message that will be sent to folder on the file system.

Common-orchestration

Again, I will not explain all the steps to create the entire flow of the orchestration. The most important thing here is to define the “Type Modifier” property of the orchestration.

If we make an analogy with C#, we can say that this property is the same as the Accessibility Levels to C# members or types. The “Type Modifier” property defines the scope of an Orchestration, i.e., it indicates the access restrictions to this Orchestration. An Orchestration can be public, private, or internal.

  • If it is Public, it is visible to anyone interacting with the orchestration.
  • If it is Private, it is visible to other orchestrations within the same project and namespace.
  • If it is Internal, the port type is visible only within the project.

When we create an Orchestration, the default “Type Modifier” is “Internal”. So to be able to call this orchestration from a different Visual Studio Solution or different project we need to set the “Type Modifier” to “Public”.

To set the “Type Modifier” property for an orchestration to “Public” you need to:

  • Open the orchestration in Microsoft Visual Studio
  • Right-click somewhere in the orchestration designer (except in the shapes otherwise you will go to the shape properties), for example the green start shape at the top of the orchestration and select the “Properties Windows” option to display the Orchestration Properties dialog

Common-orchestration-type-modifier-public

  • Set the “Type Modifier” property to Public as you see in the picture.

Compile and deploy the solution.

Creating the Main Solution: CallExternalOrchestrationMainSolution

The second project, basically contains one orchestration that will receive an input message from a folder on the file system and will call a common (or external) orchestration.

Main-Orchestration

Again, I will not explain all the steps to create the entire flow of the orchestration. The most important thing here is to import the reference (DLL) that contain the common orchestration that we want to call.

To import the reference to your project you need to:

  • In Solution Explorer, right-click in “References” and select “Add Reference”.
  • In the “Add Reference” dialog box, select the “Browse” tab that enables you to browse for a component in the file system.
  • Select the components you want to reference, and then click OK.
    • You can select multiple components by holding down the CTRL key, provided the components are all on the same tab.

Now if you drag a “Call Orchestration” shape to your orchestration you will be able to select the common orchestration that we create earlier, as you can see in the picture bellow:

call-orchestration-configuration

Once again, compile and deploy the solution.

Download the sample:

How to Call Orchestrations developed in a different Visual Studio Solution (206.2 KB)
Microsoft | MSDN Code Gallery

Well, I decided to take a few minutes of my vacation to play a little with … BizTalk, renew some knowledge, answer a few emails and maybe try to answer some questions on the forums.

This exercise (or pattern) is actually from a question that I found on the forums: Reg BizTalk Mapping, which I found interesting.

So what’s the best way to map some values from a repeating node into a single node base in some conditions?

Note: you can find all mapping logic of this exercise in the forum, however briefly we have a repeating node “TimeSeries” and based on Path attribute value of “TimeSeries” node we will map on some elements of the output message:

  • If “Path” attribute == “1” then assign the value of “TimedValue” to “Quantity”
  • If “Path” attribute == “2” then assign the value of “TimedValue” to “NRJQuantity”
  • If “Path” attribute == “3” then assign the value of “TimedValue” to “AvgCal”
  • If “Path” attribute == “4” then assign the value of “TimedValue” to “AvgDens”
First Solution: Using only functoids (without custom XSLT)

To solve this mapping problem using this approach, for each element in the destination schema we need to drag:

  • One Equal functoid and drag a link from the attribute “Path” in the source schema to this functoid, this will be the first input parameter in the functoid
    • And in the second parameter we need to put the number that we want to find, in this case: “1”.
  • Drag a Value Mapping functoid to the grid
    • Drag a link from the Equal functoid to this Value Mapping functoid
    • Drag a link from the “TimedValue” element in the source element to the Value Mapping functoid
  • Drag a link from the Equal functoid for the element in question in the destination schema, in this case “Quantity” element
  • And finally we need to drag a link from the Value Mapping functoid to the respective element in the destination schema, in this case again “Quantity” element as you can see in the picture bellow.

map-values-from-repeating-node-into-single-node-using-conditions-with-functoids

  • We need to repeat the above steps for all the element until we get the following map:

map-values-from-repeating-node-into-single-node-using-conditions-with-functoids-all

This solution is correct and in fact is what’s normally we found in this type of mapping problems however this is not the best option in terms of performance. If we analyze the XSLT regenerated by the BizTalk mapping engine by:

  • Right-click in the map and select the option “Validate Map”
  • In the Output windows, press CRTL key and click on the link of “The file in the output XSLT is stored in the following file”, it will open this file in a new windows
  • Right-click and select “View Source” option

We will see that for each element in the destination schema it will be one for-each element:

<ns0:Req>
  <xsl:for-each select="TimeSeries">
    <xsl:variable name="var:v1" select="userCSharp:LogicalEq(string(@Path) , &quot;1&quot;)" />
    <xsl:if test="$var:v1">
      <xsl:variable name="var:v2" select="string(@Path)" />
      <xsl:variable name="var:v3" select="userCSharp:LogicalEq($var:v2 , &quot;1&quot;)" />
      <xsl:if test="string($var:v3)='true'">
        <xsl:variable name="var:v4" select="TimedValues/TimedValue/text()" />
        <ns0:Quantity>
          <xsl:value-of select="$var:v4" />
        </ns0:Quantity>
      </xsl:if>
    </xsl:if>
  </xsl:for-each>

  <xsl:for-each select="TimeSeries">
    <xsl:variable name="var:v5" select="string(@Path)" />
    <xsl:variable name="var:v6" select="userCSharp:LogicalEq($var:v5 , &quot;2&quot;)" />
    <xsl:if test="$var:v6">
      <xsl:if test="string($var:v6)='true'">
        <xsl:variable name="var:v7" select="TimedValues/TimedValue/text()" />
        <ns0:NRJQuantity>
          <xsl:value-of select="$var:v7" />
        </ns0:NRJQuantity>
      </xsl:if>
    </xsl:if>
  </xsl:for-each>
....

This means that if we have 50 occurrences of “TimeSeries” node, we will have 50 iterations for each element that we want to map in the destination schema… so this approach may be easy to implement and somewhat acceptable in small messages is extremely disadvantageous for large message.

Limitations of this approach:

  • Lack of performance
Second Solution: Using Inline XSLT

In this second approach what we will do is take the XSLT code generated by the compiler and optimize it by removing all unnecessary cycles and put this code in a Scripting functoid.

To accomplish this, we need to:

  • Drag Scripting functoid to the map grid
    • In the scripting type select “Inline XSLT” option
    • In the Inline script put the following code:
<xsl:for-each select="TimeSeries">
  <xsl:if test="string(@Path) = '1' ">
    <Quantity>
      <xsl:value-of select="TimedValues/TimedValue/text()" />
    </Quantity>
  </xsl:if>
  <xsl:if test="string(@Path) = '2' ">
    <NRJQuantity>
      <xsl:value-of select="TimedValues/TimedValue/text()" />
    </NRJQuantity>
  </xsl:if>
  <xsl:if test="string(@Path) = '3' ">
    <AvgCal>
      <xsl:value-of select="TimedValues/TimedValue/text()" />
    </AvgCal>
  </xsl:if>
  <xsl:if test="string(@Path) = '4' ">
    <AvgDens>
      <xsl:value-of select="TimedValues/TimedValue/text()" />
    </AvgDens>
  </xsl:if>
</xsl:for-each>
  • Finally drag a link from the Scripting functoid to one element in the destination schema, for example “NRJQuantity”

map-values-from-repeating-node-into-single-node-using-conditions-with-scripting

Limitations of this approach:

  • May have some lack of performance if we work with large message because some unnecessary iterations in the cycle, however it is far more efficient than the first solution.
  • Some warnings saying that some required field has no incoming link.
  • Because we use scripting functoids we cannot read the entire map visually. We need to open the functoids and read, mainly, the XSLT code.
Third Solution: Using Inline XSLT along with XPath queries

After analyzing all the advantages and disadvantages, I decided that I could optimize even more the XSLT script in order to have a better performance but to do this I would have to use a different approach than the one that was used by the BizTalk mapper engine, and for me this is the best approach to accomplish this type of mapping problem, because basically solves all limitations of previous solutions: it’s easy to create (only need basic knowledge of XSLT and XPath) and don’t have performance problems.

To accomplish this, we need to:

  • Replace the code of the Scripting functoid, existing in the previous solution, by:
<xsl:choose>
  <xsl:when test="count(//TimeSeries[@Path='1']) > 0">
    <Quantity>
      <xsl:value-of select="//TimeSeries[@Path='1']/TimedValues/TimedValue/text()" />
    </Quantity>
  </xsl:when>
</xsl:choose>
<xsl:choose>
  <xsl:when test="count(//TimeSeries[@Path='2']) > 0">
    <NRJQuantity>
      <xsl:value-of select="//TimeSeries[@Path='2']/TimedValues/TimedValue/text()" />
    </NRJQuantity>
  </xsl:when>
</xsl:choose>
<xsl:choose>
  <xsl:when test="count(//TimeSeries[@Path='3']) > 0">
    <AvgCal>
      <xsl:value-of select="//TimeSeries[@Path='3']/TimedValues/TimedValue/text()" />
    </AvgCal>
  </xsl:when>
</xsl:choose>
<xsl:choose>
  <xsl:when test="count(//TimeSeries[@Path='4']) > 0">
    <AvgDens>
      <xsl:value-of select="//TimeSeries[@Path='4']/TimedValues/TimedValue/text()" />
    </AvgDens>
  </xsl:when>
</xsl:choose>

map-values-from-repeating-node-into-single-node-using-conditions-with-scripting-2

Limitations of this approach:

  • Because we use scripting functoids we cannot read the entire map visually. We need to open the functoids and read, mainly, the XSLT code.
  • Need basic knowledge of XSLT and XPath
  • Some warnings saying that some required field has no incoming link.
Fourth Solution: Using Inline XSLT along with XPath queries (avoiding warnings)

So to avoid warnings saying that some required field has no incoming link we must split the XSLT code that we use in the last solution (Third Solution) in different blocks for each element in the destination schema

To accomplish this, we need to:

  • Drag four Scripting functoid to the map grid and drag a link from each Scripting functoid to each element in the destination schema
  • For each Scripting functoid:
    • In the scripting type select “Inline XSLT” option
    • In the Inline script put the code that corresponding to the element in the destination element, for example in the first:
<xsl:choose>
  <xsl:when test="count(//TimeSeries[@Path='1']) > 0">
    <Quantity>
      <xsl:value-of select="//TimeSeries[@Path='1']/TimedValues/TimedValue/text()" />
    </Quantity>
  </xsl:when>
</xsl:choose>

map-values-from-repeating-node-into-single-node-using-conditions-with-scripting-3

Limitations of this approach:

  • Because we use scripting functoids we cannot read the entire map visually. We need to open the functoids and read, mainly, the XSLT code.
  • Need basic knowledge of XSLT and XPath

The sample code is available for download in Code Gallery:.

How to map values from a repeating node into a single node using conditions (142.6 KB)
Microsoft Code Gallery

Sometimes people want to start learning BizTalk and don’t know where to start and it is very normal to see a lot of people asking this question, which leads me to always be looking for this information.

To be honest, it is more usual people asking “How can I learn to be a BizTalk Developer” than “How can I learn to be a BizTalk Administrator”, however BizTalk Administrator plays a very important role in BizTalk environments.

Therefore to have a quick response to this type of request and also to act as reference for administrators and developers, I decided to create two articles on the Microsoft TechNet Wiki that will act as Quick reference to all available resources:

Training-Resources-BizTalk-Developer

Training-Resources-BizTalk-Administrators

I hope you find this information useful and I challenge (invite) all BizTalk Administrator and Developers to help improve this article with new content: whitepaper’s, Microsoft documentation, tutorials, scripts, Webcast and so on…

Last couple of months I have written and edited a number of wiki articles for TechNet Wiki. The TechNet Wiki is a place, where content is generated by the community (like myself, Tord Glad Nordahl, Steef-Jan Wiggers, Howard S. Edidin, Saravana Kumar, Michael Stephenson, Dan Rosanova, Lex Hegt and many more) and Microsoft employees about Microsoft technologies and products for the community. Below you will find a list of my most recent wiki articles on BizTalk:

Contributions in English:

  • BizTalk Server: List of Custom Adapters: There are a number of open source adapters that can aid you as BizTalk developer. These adapters are not the out of the box offered by BizTalk Server: BizTalk Server Adapter pack (that provides connectivity to SAP, Siebel, SQL and many more). This article is intended to be a knowledge base of all BizTalk open sources adapters that are available.
  • BizTalk Server: List of Third-Party Adapters: Adapters for a BizTalk server represent the fundamental foundation by which interoperability between different IT systems is possible – they’re responsible for sending and receiving messages to and from the BizTalk server and different applications. There are a great post from Stephen W. Thomas that addresses this question: BizTalk Adapters: Buy, Build, or CodePlex.This article is intended to be a knowledge base of all Third-Party BizTalk adapters that are available.
  • BizTalk Server: Transform text files (Flat Files) into XML: Transformations are one of the most common components in the integration processes. They act as essential translators in the decoupling between the different systems to connect. This article aims to help you understand the process of transforming a text file (also called Flat Files) in an XML document using BizTalk Server Flat File Schemas. This article intends to be an introductory note for whom is taking the first steps in this technology.
  • Microsoft BizTalk Server seen by the programmer’s eyes: Much has been said already about the BizTalk Server platform, what it is, and the advantages offered to the organizations. For the more distracted ones, BizTalk Server is the Microsoft platform of excellence for the integration of systems and business processes. But what are the benefits that this platform offers to programmers (or developers)?
  • BizTalk Server: BizTalk Mapper Patterns: This article will provide you with common mapper problems and solutions, i.e., some BizTalk Mapper Patterns specifying best practices and some of the best ways to address some of your needs within the context of message transformation and also to enhance your skills when using the BizTalk Server Mapper.
  • Installing and configuring BizTalk Server 2010 in a Standalone machine: This guide describes the process for installing and configuring Microsoft BizTalk Server 2010 on a single computer (standalone machine) running Windows Server 2008 R2 . This information will help you plan the installation and configuration of BizTalk Server 2010, applications and components on which it depends.

Contributions in Portuguese:

  • BizTalk Server – Transformar arquivos de texto (Flat Files) em XML: Normalmente associamos as transformações de documentos aos mapas de BizTalk, mas a realidade é que existem dois tipos de transformações: as de estrutura (semântica) e as de representação (sintaxe). Estas últimas tipicamente ocorrem à entrada ou saída do BizTalk Server. Este artigo tem como objectivo ajudá-lo a compreender o processo de transformação de arquivos de texto (também chamados de Flat Files) num documento XML, bem como na validação da informação neles contida.

Feel free to edit, change and add content! And I hope you will find these articles useful.

MSDN Code Gallery (now Developer Code Samples) is your destination for downloading sample applications and code snippets, as well as sharing your own resources. Below you will find a list of my most recent Code Gallery project on BizTalk and Windows Azure Service Bus EAI & EDI:

TechNet Gallery is your destination for finding resources written in VB Script, PowerShell, SQL, JavaScript, or other script languages, or other kind of resources (docs, Visio file and so on). Below you will find a list of my most recent contributions on BizTalk:

I hope you will find these contributions useful.

In my last mapping pattern post, I explained how and described the pros and cons of four methods to accomplish a mapping from hierarchical schema to a name value pair… so the logically next step would be to describe the inverse process.

When I decided to implement this mapping I really thought it would be extremely simple and almost not worth talking about… how I was wrong! It became really complicated, and exciting, as I tried to find a solution to optimize and improve the map.

As a developer the first approach we think is to try to solve this mapping problem using only the available functoids, i.e. without custom XSLT. I quickly discarded this option and you will see why.

Note: Before I start the solution for this problem we need to notice that two element are mapped directly:

  • “Id” to “NProcesso”
  • and “ServiceName” to “ServiceName”
First Solution: Using only functoids (without custom XSLT)

To solve this mapping problem using this approach, for each element in the destination schema we need to drag:

  • One Equal functoid and drag a link from the element “Name” in the source schema to this functoid, this will be the first condition in the functoid
    • And in the second condition we need to put the element name of the destination schema that we try to map, for example “Type”.
  • Drag a Value Mapping (Flattening) functoid to the grid
    • Drag a link from the Equal functoid to this Value Mapping (Flattening) functoid
    • Drag a link from the “Value” element in the source element to the Value Mapping (Flattening) functoid
    • And finally we need to drag a link from the Value Mapping (Flattening) functoid to the respective element in the destination schema, in this case “Type” element as you can see in the picture bellow:

Name-value-to-hierarchical-using-only-functoids

  • We need to repeat the above steps for all the element except the “IPRoute” element, until we get the following map:

Name-value-to-hierarchical-using-only-functoids-2

  • Because “IPRoute” element is a repeating element, we need to take a different approach:
    • We need to drag a Looping functoid and drag a link from “Property” record in the source schema to this functoid and then drag a link from the Looping functoid to the “IPRoute” element in the destination schema
    • Then we need to make the exact same steps described earlier (Equal functoid and Value Mapping (Flattening) functoid)
    • But because we want to create the “IPRoute” element ONLY if the name is equal to “IPRoute”, then we need to drag a link from the Equal functoid to the “IPRoute” element in the destination schema.

Name-value-to-hierarchical-using-only-functoids-3

And this is it, it seems simple and it is!! However, this approach suffers from a serious problem that we can only detect by analyzing the XSLT regenerated by the BizTalk mapping engine: Performance!

If we analyze the XSLT regenerated by the BizTalk mapping engine by:

  • Right-click in the map and select the option “Validate Map”
  • In the Output windows, press CRTL key and click on the link of “The file in the output XSLT is stored in the following file”, it will open this file in a new windows
  • Right-click and select “View Source” option

We will see that for each element in the destination schema it will be one for-each element:

<xsl:for-each select="Properties/Property">
  <xsl:variable name="var:v1" select="userCSharp:LogicalEq(string(Name/text()) , &quot;Type&quot;)" />
  <xsl:if test="string($var:v1)='true'">
    <xsl:variable name="var:v2" select="Value/text()" />
    <Type>
      <xsl:value-of select="$var:v2" />
    </Type>
  </xsl:if>
</xsl:for-each>
<xsl:for-each select="Properties/Property">
  <xsl:variable name="var:v3" select="string(Name/text())" />
  <xsl:variable name="var:v4" select="userCSharp:LogicalEq($var:v3 , &quot;Protocol&quot;)" />
  <xsl:if test="string($var:v4)='true'">
    <xsl:variable name="var:v5" select="Value/text()" />
    <Protocol>
      <xsl:value-of select="$var:v5" />
    </Protocol>
  </xsl:if>
</xsl:for-each>

This means that if we have 50 occurrences of “Property” record, each filled with the elements Name and Value, we will have 50 iterations for each element that we want to map in the destination schema… in this scenario we have 12 elements, this means 600 iterations and will be worse if we are working with large maps or with high amounts of “Property” record occurrence.

Limitations of this approach:

  • Lack of performance
  • If the destination schema has many elements it takes to much work to do this kind of mapping and because we need many links and functoids to do this simple task it may become difficult to read the map.
  • If we add a new element in the destination schema, it requires that we have to rectify the mapping
Second Solution: Dynamic mapping using Inline XSLT

I soon realized that if I wanted a really good and effective solution, I would have to use custom XSLT.

And the second approach that I thought was trying to make a dynamic mapping, similarly to the third solution that I have accomplished in the “BizTalk Mapper Patterns: How to Map Hierarchical Schema to a Name Value Pair” problem

To accomplish this, we need to:

  • Drag Scripting functoid to the map grid
    • In the scripting type select “Inline XSLT” option
    • In the Inline script put the following code:
<xsl:for-each select="/s0:Provisioning/Properties/Property">
  <xsl:if test="Name/text()!='IPRoute'">
    <xsl:element name="{normalize-space(*[local-name()='Name']/text())}">
      <xsl:value-of select="Value/text()"/>
    </xsl:element>
  </xsl:if>
</xsl:for-each> 

Finally drag a link from the Scripting functoid to the “Type” element in the destination schema:

Name-value-to-hierarchical-Dynamic-mapping-using-Inline-XSLT

This looked like be my favorite approach because is complete dynamic. If another element was added to the destination schema I didn’t need to fix the mapping!

But unfortunately this approach has several serious limitations.

Limitations of this approach:

  • The script only work well if all the elements contained in the “Properties” record, are coming filled in the correct order of the elements in the destination schema.
  • Don’t work with nested records (or sub-records), if you notice in the script I ignore all “IPRoute” names

I could probably find other limitations but for me these two are enough to discard this approach.

Third Solution: Using Inline XSLT along with XPath queries

After analyzing all the advantages and disadvantages, for me this is the best (only) approach to accomplish this type of mapping problem. Again, because basically solves all limitations of previous solutions: it’s easy to create (only need basic knowledge of XSLT and XPath) and don’t have performance problems.

To accomplish this, we need to:

  • Replace the code of the Scripting functoid, existing in the previous solution, by:
<Type>
  <xsl:value-of select="//Properties/Property[Name='Type']/Value/text()" />
</Type>
<Protocol>
  <xsl:value-of select="//Properties/Property[Name='Protocol']/Value/text()" />
</Protocol>
<Pool>
  <xsl:value-of select="//Properties/Property[Name='Pool']/Value/text()" />
</Pool>
<VPNName>
  <xsl:value-of select="//Properties/Property[Name='VPNName']/Value/text()" />
</VPNName>
<IPAddress>
  <xsl:value-of select="//Properties/Property[Name='IPAddress']/Value/text()" />
</IPAddress>
<IPNetmask>
  <xsl:value-of select="//Properties/Property[Name='IPNetmask']/Value/text()" />
</IPNetmask>
<LAN>
  <xsl:for-each select="Properties/Property[Name='IPRoute']">
    <IPRoute>
      <xsl:value-of select="./Value/text()" />
    </IPRoute>
  </xsl:for-each>
</LAN>
<VirtualRouter>
  <xsl:value-of select="//Properties/Property[Name='VirtualRouter']/Value/text()" />
</VirtualRouter>
<IdleTimeout>
  <xsl:value-of select="//Properties/Property[Name='IdleTimeout']/Value/text()" />
</IdleTimeout>
<SessionTimeout>
  <xsl:value-of select="//Properties/Property[Name='SessionTimeout']/Value/text()" />
</SessionTimeout>
<TunnelType>
  <xsl:value-of select="//Properties/Property[Name='TunnelType']/Value/text()" />
</TunnelType>

Name-value-to-hierarchical-Dynamic-mapping-using-Inline-XSLT

In this first approach, I tried to keep the code simple, but there is an important limitation in this code … I’m not validate the existence of optional fields. To do that we need to put the code a little more elaborate:

<xsl:choose>
  <xsl:when test="count(//Properties/Property[Name='Type']) > 0">
    <Type>
      <xsl:value-of select="//Properties/Property[Name='Type']/Value/text()" />
    </Type>
  </xsl:when>
</xsl:choose>
<xsl:choose>
  <xsl:when test="count(//Properties/Property[Name='Protocol']) > 0">
    <Protocol>
      <xsl:value-of select="//Properties/Property[Name='Protocol']/Value/text()" />
    </Protocol>
  </xsl:when>
</xsl:choose>
<xsl:choose>
  <xsl:when test="count(//Properties/Property[Name='Pool']) > 0">
    <Pool>
      <xsl:value-of select="//Properties/Property[Name='Pool']/Value/text()" />
    </Pool>
  </xsl:when>
</xsl:choose>
<xsl:choose>
  <xsl:when test="count(//Properties/Property[Name='VPNName']) > 0">
    <VPNName>
      <xsl:value-of select="//Properties/Property[Name='VPNName']/Value/text()" />
    </VPNName>
  </xsl:when>
</xsl:choose>
<xsl:choose>
  <xsl:when test="count(//Properties/Property[Name='IPAddress']) > 0">
    <IPAddress>
      <xsl:value-of select="//Properties/Property[Name='IPAddress']/Value/text()" />
    </IPAddress>
  </xsl:when>
</xsl:choose>
<xsl:choose>
  <xsl:when test="count(//Properties/Property[Name='IPNetmask']) > 0">
    <IPNetmask>
      <xsl:value-of select="//Properties/Property[Name='IPNetmask']/Value/text()" />
    </IPNetmask>
  </xsl:when>
</xsl:choose>
<xsl:choose>
  <xsl:when test="count(//Properties/Property[Name='IPRoute']) > 0">
    <LAN>
      <xsl:for-each select="Properties/Property[Name='IPRoute']">
        <IPRoute>
          <xsl:value-of select="./Value/text()" />
        </IPRoute>
      </xsl:for-each>
    </LAN>
  </xsl:when>
</xsl:choose>
<xsl:choose>
  <xsl:when test="count(//Properties/Property[Name='VirtualRouter']) > 0">
    <VirtualRouter>
      <xsl:value-of select="//Properties/Property[Name='VirtualRouter']/Value/text()" />
    </VirtualRouter>
  </xsl:when>
</xsl:choose>
<xsl:choose>
  <xsl:when test="count(//Properties/Property[Name='IdleTimeout']) > 0">
    <IdleTimeout>
      <xsl:value-of select="//Properties/Property[Name='IdleTimeout']/Value/text()" />
    </IdleTimeout>
  </xsl:when>
</xsl:choose>
<xsl:choose>
  <xsl:when test="count(//Properties/Property[Name='SessionTimeout']) > 0">
    <SessionTimeout>
      <xsl:value-of select="//Properties/Property[Name='SessionTimeout']/Value/text()" />
    </SessionTimeout>
  </xsl:when>
</xsl:choose>
<xsl:choose>
  <xsl:when test="count(//Properties/Property[Name='TunnelType']) > 0">
    <TunnelType>
      <xsl:value-of select="//Properties/Property[Name='TunnelType']/Value/text()" />
    </TunnelType>
  </xsl:when>
</xsl:choose>

Limitations of this approach:

  • Because we use scripting functoids we cannot read the entire map visually. We need to open the functoids and read, mainly, the XSLT code.
  • Need basic knowledge of XSLT and XPath
  • If we add a new element in the destination schema, it requires that we have to rectify the mapping

The sample code is available for download in Code Gallery:.

BizTalk Mapper Patterns: How to Map Name Value Pair to a Hierarchical Schema (59.2 KB)
Microsoft Code Gallery

In this new mapping pattern I want to show you how can you transform an hierarchical schema into a Name/Value Pair record.

The first thing we need to know is how I can read the name of the element from the source schema. By default when we drag a link from the source to the destination schema, the value of the element is mapped in the destination schema, but we can change this behavior in the link properties by choosing “Copy name” in the “Source Links” property:

Copy-name-link-property

So to reach our goal we need to link for the source to the destination schema:

  • The link to the “Name” element set with “Copy name” in the “Source Links” property
  • And the link to the “Value” element set with “Copy text value” (the default value) in the “Source Links” property

first-graft-mapping-name-value

Note: Before I start the solution for this problem we need to notice that two element are mapped directly:

  • “NProcesso” to “Id”
  • and “ServiceName” to “ServiceName”

And one element is not mapped “Tipo_Operacao”. All other elements need to be mapped in the Name/Value Pair record.

First Solution: Using only Links

The first approach we think is to mapped all the element using the method previously explained.

mapping-name-value-using-links-1

However this approach have a problem because don’ the produce a valid message, instead of creating a record for each different element mapped he gathers all the Names and Values ​​in a single record:

<ns0:Provisioning xmlns:ns0="http://SandroPereira.MappingToNameValueRecord.Provisioning">
  <Id>Nprocesso_0</Id>
  <Properties>
  <Property>
  <Name>IPRoute</Name>
  <Name>Type</Name>
  <Name>Protocol</Name>
  <Name>Pool</Name>
  <Name>VPNName</Name>
  <Name>IPAddress</Name>
  <Name>IPNetmask</Name>
  <Name>Profile</Name>
  <Name>VirtualRouter</Name>
  <Name>IdleTimeout</Name>
  <Name>SessionTimeout</Name>
  <Name>TunnelType</Name>
  <Value>IPRoute_0</Value>
  <Value>Type_0</Value>
  <Value>Protocol_0</Value>
  <Value>Pool_0</Value>
  <Value>VPNName_0</Value>
  <Value>IPAddress_0</Value>
  <Value>IPNetmask_0</Value>
  <Value>Profile_0</Value>
  <Value>VirtualRouter_0</Value>
  <Value>IdleTimeout_0</Value>
  <Value>SessionTimeout_0</Value>
  <Value>TunnelType_0</Value>
  </Property>
  <ServiceName>ServiceName_0</ServiceName>
</ns0:Provisioning>

To solve this problem we need to add a Lopping functoid and map all the elements in this functoid:

mapping-name-value-using-links-2

Limitations of this approach:

  • If the source schema has many elements it takes much work to do this kind of mapping and because we need many links to do this simple task it may become difficult to read the map.
  • We’re not validate the existence of optional elements, which causes too many warnings
  • A new element in the source schema requires that we have to rectify the mapping
Second Solution: Using only Links and validate the existence of optional elements

So to avoid warnings of optional elements in the first approach we need to use additional functoids. For each element mapped in the Name/Value Pair we need to drag:

  • One Logical Existence functoid and drag a link from the source element to this functoid
  • And two Value Mapping functoids:
    • Drag a link from the Logical Existence functoid to the first Value Mapping functoid
    • Drag a link from the Logical Existence functoid to the second Value Mapping functoid
    • Drag a link from the source element to the first Value Mapping functoid and in the link properties set with “Copy name” the “Source Links” property
    • Drag a link from the source element to the second Value Mapping functoid and in the link properties set with “Copy text value” the “Source Links” property
    • Drag a link from the first Value Mapping functoid to the element “Name” in the destination schema
    • Drag a link from the second Value Mapping functoid to the element “Value” in the destination schema

mapping-name-value-using-links-handling-opcionals

Limitations of this approach:

  • If the source schema has many elements it takes much work to do this kind of mapping and because we need many links and functoids to do this simple task it may become difficult to read the map.
  • A new element in the source schema requires that we have to rectify the mapping
Third Solution: Using Inline XSLT

This is my favorite approach and why? Because basically solves all limitations of previous solutions: Too many work, too many links and functoids and most important can be complete dynamic, i.e., if another element is added to the source schema I don’t need to fix the mapping!

So how can we accomplish this dynamic mapping?

We need to add to the grid two Scripting functoids:

  • The first scripting functoid is for create a C# function to validate the existence of the element.
    • In the scripting type select “Inline C#” option
    • In the Inline script put the following code:
public string EmptyOrNull(string param)
{
     if(string.IsNullOrEmpty(param))
	return "false";
     return "true";
}
  • The second scripting functoid is for mapping all the element in the Name/Value Pair
    • In the scripting type select “Inline XSLT” option
    • In the Inline script put the following code:
<xsl:element name="Properties">
      <xsl:for-each select="/s0:Request/Body/*">
              <xsl:variable name="var:v2">
                     <xsl:value-of select="."/>
              </xsl:variable>
              <xsl:variable name="var:v1" select="userCSharp:EmptyOrNull(string($var:v2))" />
              <xsl:if test="local-name()!='ServiceName' and local-name()!='LAN' and $var:v1='true'">
                  <xsl:element name="Property">
                     <xsl:element name="Name">
                             <xsl:value-of select="local-name()"/>
                      </xsl:element >
                      <xsl:element name="Value">
                             <xsl:value-of select="."/>
                      </xsl:element >
                </xsl:element>
              </xsl:if>
       </xsl:for-each>
       <xsl:for-each select="/s0:Request/Body/LAN/*">
              <xsl:variable name="var:v2">
                     <xsl:value-of select="."/>
              </xsl:variable>
              <xsl:variable name="var:v1" select="userCSharp:EmptyOrNull(string($var:v2))" />
              <xsl:if test="$var:v1='true'">
                     <xsl:element name="Property">
                     <xsl:element name="Name">
                            <xsl:value-of select="local-name()"/>
                     </xsl:element >
                     <xsl:element name="Value">
                           <xsl:value-of select="."/>
                     </xsl:element >
                     </xsl:element>
              </xsl:if>
       </xsl:for-each>
</xsl:element>

Finally drag a ling from the second scripting functoid to the “Properties# record in the destination schema:

mapping-name-value-using-inline-xslt

Limitations of this approach:

  • Because we use scripting functoids we cannot read the entire map visually. We need to open the functoids and read, mainly, the XSLT code.
Fourth Solution: Using Table Looping functoid

Finally I decided to create a fourth approach using the capabilities of the Table Looping functoid. For me the big difference between this approach and the first two is that is probably to be easier to read.

So instead of using the looping functoid and drag all links from the source directly to the destination schema, we will drag the links all the links from the source schema to the Table Looping functoid… but because you cannot drag to link from the same element to the Table Looping functoid (To map the name and the value) you need to use a workaround:

  • Drag a Table Looping functoid to the map grid
  • For each element drag a String Concatenate functoid to the map grid
    • Drag a link from the source element to the String Concatenate functoid and in the link properties set with “Copy name” the “Source Links” property
    • Drag a link from the String Concatenate functoid to the Table Looping functoid and in the link properties set the “Label” property to the following text “<Element name> Name” (note: your need to change <Element name> to the element concerned, ex: “Type Name”)
    • Drag a link from the source element to the Table Looping functoid and in the link properties set with “Copy text value” the “Source Links” property

In the Table lopping functoid configuration we need to set the first to inputs:

  • The first with the number of element mapped in the Table lopping functoid
  • The second with the number of columns, in this case 2

Table-looping-functoid-configuration

And in the Table Lopping grid we need to manually associate the first column the name of element and in the second the value of the element:

Table-looping-functoid-configuration-2

Finally we need to drag to Table Extractor functoid and configure them to read the first and the second column of the table:

mapping-name-value-using-table-lopping-functoid

Limitations of this approach:

  • If the source schema has many elements it takes much work to do this kind of mapping and because we need many links and functoids to do this simple task it may become difficult to read the map.
  • We’re not validate the existence of optional elements, which causes too many warnings.
  • A new element in the source schema requires that we have to rectify the mapping

The sample code in Code Gallery as this workaround implemented.

BizTalk Mapper Patterns: How to Map Hierarchical Schema to a Name Value Pair (69.3 KB)
Microsoft TechNet Gallery

This topic is not new in my blog, I’ve already talked about this in the past: Calling an external assembly from Custom XSLT – Custom Extension XML (Grid Property) however, I decided to revisit this functionality within BizTalk Server 2010 and you will know why soon.

So is usual in complex maps to have scripting functoid with custom inline XSLT, and sometimes is useful to call custom .Net components directly from XSLT.

Create .Net Component

To illustrate this functionality, I decided to create a Class Library project: MapperExtensionsFunctions with a simple class where it is implemented a method to format the numbers in three decimal places:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace MapperExtensionsFunctions
{
    public class MappingFunctions
    {
        public MappingFunctions()
		{
		}

        public string ToDecimalPoint(string Input)
        {
            CultureInfo ciEN = new CultureInfo("en-US", false);

            double ConvertionDouble = double.Parse(Input, ciEN);
            string Output = string.Format("{0:0.000}", ConvertionDouble);
            return Output;
        }
    }
}
How can we extend BizTalk map to support this functionality?

You can add a custom extension xml file to your solution in order to declare the namespace and use a method from a .Net assembly from XSLT.

The extension file should look something like this:

<ExtensionObjects>
  <ExtensionObject Namespace="http://schemas.microsoft.com/BizTalk/2003/ScriptNS0" AssemblyName="MapperExtensionsFunctions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cdbffba4cc751306" ClassName="MapperExtensionsFunctions.MappingFunctions" />
</ExtensionObjects>

Note: “http://schemas.microsoft.com/BizTalk/2003/ScriptNS0” is the “default namespace”, however you can change it (see more here)

In the properties of your BizTalk Mapper, use the Custom Extension XML property to open the Select Custom Extension XML File dialog box, in which you can select the file that contains the custom extension XML for the map (file above).

Custom-Extension-XML

Finally in your Inline XSLT functoid you can use the methods from the assembly by:

<xsl:variable name="result" xmlns:ScriptNS0="http://schemas.microsoft.com/BizTalk/2003/ScriptNS0" select="ScriptNS0:ToDecimalPoint(MarketPrice/text())" />

Or in this case, inside Inline XSLT Call Template:

<xsl:template name="PriceTemplate">
  <xsl:param name="market" />
  <xsl:param name="owner" />
  <xsl:element name="Price">
    <xsl:variable name="pmarket" xmlns:ScriptNS0="http://schemas.microsoft.com/BizTalk/2003/ScriptNS0" select="ScriptNS0:ToDecimalPoint($market)" />
    <xsl:variable name="powner" xmlns:ScriptNS0="http://schemas.microsoft.com/BizTalk/2003/ScriptNS0" select="ScriptNS0:ToDecimalPoint($owner)" />
    <PriceMarket>
      <xsl:value-of select="$pmarket" />
    </PriceMarket>
    <PriceOwner>
      <xsl:value-of select="$powner" />
    </PriceOwner>
  </xsl:element>
</xsl:template>
Houston we have a problem!

After Build, deploy and configure my project with success I decided to test my solution, but I keep getting the following error:

The Messaging Engine failed while executing the inbound map for the message coming from source URL:”C:\TEMP\PORTS\IN_CAR\*.xml” with the Message Type “http://BizTalk.CallingExternalAssemblyFromInlineXSLT.CarInfo#CarProperty&#8221;. Details:”Cannot find the script or external object that implements prefix ‘ScriptNS0’.”

At first glance, this error suggests that the assembly in question is not published in the GAC… However even after re-publish, the assembly in the GAC the problem remained!

Don’t panic, believe it or not, you did everything right… BizTalk Server 2010/Visual Studio 2010 have a bug (or issue): Visual Studio does not persist the path of Custom Extension XML property in the .BTM file.

So if someone wishes to use an external assembly in via a Inline XSLT/XSLT Template scripting functoid they cannot specify the external assembly through an extension xml file.

I tried to install the latest cumulative update package for BizTalk (CU5) and Visual Studio service pack but the issue still remain active (you can see more detail and vote to fix it here)

Workaround (unfortunately it’smanual)

You need to manually edit .BTM file to add this node between the elements </ScriptTypePrecedence> and <TreeValues>:

<CustomXSLT XsltPath="" ExtObjXmlPath=".\ExternalAssembly.xml" />

Note: Is not mandatory the CustomXSLT node stand between the elements </ScriptTypePrecedence> and <TreeValues> however this is normal behavior of the compiler

However this is a workaround that can cause many problems, especially maintaining this issue… but stay tuned, because in my next post I will explain how we can solve this problem in a better way.

Calling an external assembly from Custom XSLT in BizTalk Server 2010 Maps (65.9 KB)
Microsoft Code Gallery

In the following of my previous post, this is the list of my contributions in the last six months on MSDN Code Gallery and TechNet Gallery.

MSDN Code Gallery is your destination for downloading sample applications and code snippets, as well as sharing your own resources.

TechNet Gallery is your destination for finding resources written in VB Script, PowerShell, SQL, JavaScript, or other script languages, or other kind of resources (docs, Visio file and so on).

List of contributions on MSDN Code Gallery:

  • How to implement multi-level Muenchian grouping in BizTalk Maps: Inspired by a question in BizTalk Server Forums: XSLT Mapping Question (Summing Values) How can we can we performe multi-level Muenchian grouping in BizTalk Maps and perform mathematical operations on this group? I decided to solved this problem and publish this sample to help.
  • BizTalk Server – Basics principles of Maps: Maps or transformations are one of the most common components in the integration processes. They act as essential translators in the decoupling between the different systems to connect. In this article, as we explore the BizTalk Mapper Designer, we will explain its main concepts.
  • Grouping elements from different messages in BizTalk Maps: We want to combine data from two different messages into one, more specifically, we want to combine each user with his address and each user can have multiple addresses.

List of contributions on TechNet Gallery:

  • Collection of Visio 2010 Stencil for BizTalk Server: This is a collection of 37 Visio 2010 shapes for representing BizTalk physical architecture or solution diagrams in Visio 2010:BizTalk topologies, BizTalk Runtime Architecture and ESB Toolkit, Receive and Send Pipelines, Inbound and Outbound Maps, Adapters and Filters, …
  • Obtain a list of “BizTalk Software Inventory” installed with PowerShell: It’s always good to know what software is installed in our environment. Sometimes we need to know what version of BizTalk is installed or what version of the Adapter Pack, x86 or x64? And preferably be able to get this list in an easy and automated way.
  • Determining the process ID of BizTalk Host Instances: We can debug for example, external assembly’s that are called from within a BizTalk process or debugging pipeline components in run-time mode. In Visual Studio set breakpoints in your code. To debug you must attach to the BizTalk process that is running the .Net code.
  • XML-RPC Schema: This is a XML-RPC schema that you can use in BizTalk. XML-RPC, It’s a spec and a set of implementations that allow software running on disparate operating systems, running in different environments to make procedure calls over the Internet.
  • Configure BizTalk Services to start automatically after a system restart: This is a simple script to configure BizTalk Services and Enterprise Single Sign-On Service to start automatically after a system restart.

I hope you will find these contributions useful.