Mapping Scenario: Normalising and generating sequential ids
-
2012년 4월 26일 목요일 오전 7:54
This is a real world scenario that was difficult in the BizTalk mapper. I'm wondering how easy it will be to do in the new mapper...
Source
The source looks like this with a specific node name for each type of Driver
<Drivers> <MainDriver Name="Driver A" /> <AdditionalDriver Name="Driver B" /> <AdditionalDriver Name="Driver C" /> <AdditionalDriver Name="Driver D" /> </Drivers>
Target
The target looks like this and has a sequential ID.
<Drivers> <Driver Id="1" Type="Main" Name="Driver A" /> <Driver Id="2" Type="Additional" Name="Driver B" /> <Driver Id="3" Type="Additional" Name="Driver C" /> <Driver Id="4" Type="Additional"Name="Driver D" /> </Drivers>
Solution?
I'm looking at how to do this in the new mapper. The problem is generating the sequential ID.
I can see a Generate ID operation but that doesn't give me a sequential ID.
The Get Loop Index operation only gives the index within the current loop and could work if the scopes can be sorted out correctly.
So far, I've got this far:
<?xml version="1.0" encoding="utf-8"?> <ns1:Drivers xmlns:ns0="http://Denormalization.DriverSource" xmlns:ns1="http://Denormalization.DriversTarget"> <Driver Id="1" Type="Main" Name="Driver 1" /> <Driver Id="1" Type="Additional" Name="Driver 2" /> <Driver Id="2" Type="Additional" Name="Driver 3" /> </ns1:Drivers>
Another approach would be to use 2 stages. Firstly to
<?xml version="1.0" encoding="utf-8"?> <ns1:Drivers xmlns:ns0="http://Denormalization.DriverSource" xmlns:ns1="http://Denormalization.DriversTarget"> <Driver Type="Main" Name="Driver 1" /> <Driver Type="Additional" Name="Driver 2" /> <Driver Type="Additional" Name="Driver 3" /> </ns1:Drivers>
Then to:
<?xml version="1.0" encoding="utf-8"?> <ns1:Drivers xmlns:ns0="http://Denormalization.DriverSource" xmlns:ns1="http://Denormalization.DriversTarget"> <Driver Id="1" Type="Main" Name="Driver 1" /> <Driver Id="2" Type="Additional" Name="Driver 2" /> <Driver Id="3" Type="Additional" Name="Driver 3" /> </ns1:Drivers>
But:
1. The lack of a Mass Copy operation makes this a bit harder than it should be.
2. Why have 2 stages when 1 should do?
- 편집됨 Rob Henwood 2012년 4월 26일 목요일 오전 7:56
모든 응답
-
2012년 4월 26일 목요일 오전 9:20
Hi Rob,
As you correctly pointed out, we do not provide a sequential ID generation functoid.
One way to solve the scenario you mentioned, would be to create a list with n+1rows ( 1 for the main driver and n for the additional drivers) (where n=3 in your case),
and then use a mapeach functoid and use a Get LoopIndex functoid to output the required Id attribute on the target.
Hope that hepls!
Harsh
- 답변으로 제안됨 Harsh Gupta [MSFT] 2012년 4월 26일 목요일 오전 10:42
-
2012년 4월 26일 목요일 오전 9:25
OK... it can be done by adding all of the items to a list first. This is OK except for the fact that, if the source had a lot more fields, you would soon be adding many, many fields to the list and any hierarchy would be difficult to reconstruct from the list.
Here's what the successful map looks like:
- 답변으로 표시됨 Rob Henwood 2012년 4월 26일 목요일 오전 9:26
-
2012년 4월 28일 토요일 오전 10:17
Hi Harsh,
I still don't think this is optimal and I have to jump through too many hoops to get a simple operation done. I still think that, despite the new mapper being able to do the work as shown above, it could be made simpler somehow.
Thinking about other ways and technologies:
XSLT
In XSLT you could select /Drivers/* in a foreach to get any node under drivers. Then you could get the sequential index using a position() function. That's quick and easy. If you use XSLT though, you don't need the mapper, and that's what a lot of advanced BizTalk devlopers do. As soon as you don't need the mapper, some people start to question the whole platform and why they're spending so much on it - believe me, they do!
BizTalk
In the BizTalk map to solve this problem, the mapping was done in 2 stages:
1. The first to ordered everything in the correct sequence using mass copy to copy all of the sub nodes across. This created a sequential drivers structure. The map became a shared map to solve this kind of problem that appeared in about 30% of the integration scenarios.
2. The second map was then able to get the position of the sequential drivers so that sequential ids could be generated.
In the new mapper, stage 1 would be harder because there is no mass copy.
New Mapper
I think that the new mapper would benefit from being able to generate a sequential id. Since the new mapper is no longer based on XSLT, it must be easier to hold state and decide how many Driver nodes, for example, have been generated.
Another solution would be to allow the MapEach to be scoped on more than one node, but that would be harder, I suspect.
Lastly, mass copy needs to be reintroduced too.
XAML vs XLST
I fear that, because MSFT have started again, creating their own mapping technology around XAML, that they may miss some of the features that allowed XSLT to become so prevalent and useful. Don't get me wrong though, the new mapper feels better than the BizTalk mapper but it does have a way to go to become a compelling offering and ensure that developer productivity is very high.
Thanks
Rob
-
2012년 4월 28일 토요일 오후 9:00
Thanks for the screenshot of your map. I do think it seems pretty complicated for what you are actually accomplishing.
Personally, I would look at the new mapper and think it would be nice if we could use a LINQ to Xml query to build that list and then loop on the results of that. Some of the same synergies with XSLT you get with LINQ to Xml, and both are absent currently from the new mapper.
Thanks,
If this answers your question, please use the "Answer" button to say so | Ben Cline
-
2012년 4월 30일 월요일 오전 5:01
Hi Rob,
The list solution is a workaround, we had started thinking about supporting a sequential id generation functoid, which will solve this problem cleanly. Also since we will be providing a scripting functoid, this problem can be solved using that as well.
Thanks
Harsh

