BizTalk : How To : Call .Net Component inside Biztalk mapper using XSLT call template PART 1

Tuesday, March 26, 2013

post by  Richard Seroter
I encountered a particularly tricky multi-part mapping scenario. I had to build a destination message that contained groupings from the two source messages. Each record in the first source message created a destination node, and each record in the second source message created a destination node directly beneath the related first source record. To make matters tougher, every destination record has an attribute containing a sequential number. So out of this …
The destination was supposed to look like this …
  <Node1 page=”1″><Node1>
  <NodeRelatedToNode1 page=”2″></NodeRelatedToNode1>
  <NodeRelatedToNode1 page=”3″></NodeRelatedToNode1>
  <Node2 page=”4″></Node2>
  <NodeRelatedToNode2 page=”5″></NodeRelatedToNode2>
The grouping part wasn’t too tough, just used a Scripting functoid with the XSLT Call Templateand a little hand written XSL. The hard part was creating the sequential “page” numbers. Those familiar with XSLT know that the “variables” in XSLT are basically constants, so you can’t create a variable and increment it. I considered building some sort of recursion to get my incremented number, but in the end, decided to call a custom .NET component from my map’s XSLT. I built a C# component that had a member variable, and a method called “GetNext()” which incremented and then returned the next sequential number. I then set my map’s Custom Extension XML to an XML document referencing my custom component. Now in my XSLT Call Template I could get the next “page” number each time I built a destination node. Neat!
See here for an example of doing this.
Here’s where a “quirk” was introduced. When I deployed this map, and ran multiple documents through it, the first document had it’s paging correct (e.g. pages 1-5), but the next messages had the wrong values (e.g. 6-10, 11-16, etc). What was happening was that somehow this custom C# component was being shared! The “increment” kept counting on each orchestration call! My C# component wasn’t built as a “static” object, and I assumed that the scope of each custom object was the individual map (or orchestration) instance.
I still have no idea why this happened, but to ensure it wouldn’t keep happening, I added a method to the custom component called “Reset()” which set the counter to 0. Then at the top of the map I call out to that method to ensure that each map starts its counter at 0.

No comments:

Post a Comment

Post Your Comment...