Hi all
This is the second post in a series about solving the "If-Then-Else" problem in a map. In my first post I discussed how to use BizTalks built-in functionality to solve the problem. Neither of the three proposed solutions really seem nice to me, so I wondered how difficult it might be to code a custom functoid that does the trick. It turned out to be unexpectedly hard, and this post tries to clarify my findings and explain them.
So, to continue from my previous post, to me the best solution is to code your own functoid, that mimics the value mapping functoid, but adds an "else" part. So basically just a third parameter to the value mapping functoid that is returned in case the first parameter is false.
For information about how to program a custom functoid, please visit http://msdn.microsoft.com/en-us/library/aa560879.aspx - I wont go into details about that here. I will just comment on the issues I have had with creating this particular functoid.
The final solution should give me the possibility to have a map like this one:
YES, I know my icons are very bad... Anyway, three inputs: a boolean and two values.
So, getting to the code, my first try looked like this:
-- BEGIN CODEthis.SetMinParams(3);this.SetMaxParams(3);this.Category = FunctoidCategory.ValueMapping;this.OutputConnectionType = ConnectionType.AllExceptRecord;AddInputConnectionType(ConnectionType.AllExceptRecord);AddInputConnectionType(ConnectionType.AllExceptRecord);AddInputConnectionType(ConnectionType.AllExceptRecord);-- END CODE
I have removed irrelevant lines, such as setting up the resources, setting the ID, and so on.
First of all, in the code of a custom functoid, you need to specify which category the functoid should belong to. The possibilities are listed at http://msdn.microsoft.com/en-us/library/microsoft.biztalk.basefunctoids.functoidcategory.aspx. I hadn't really looked at this list, since I thought that the intellisense in VS.NET 2005 was good enough. Since my functoid is an advanced value mapping functoid, I chose he value mapping category. This turned out a but different than I thought. It turns out, that the category you assign to a custom functoid not only determines where in the toolbox it should be placed, but also sometimes some extra functionality is added to the functoid. Given my map above, I had expected that the created XSLT would just call my functoid with the three parameters and then my code would do the rest. But the generated XSLT looks like this:
<?xml version="1.0" encoding="UTF-16"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var" exclude-result-prefixes="msxsl var s0 userCSharp" version="1.0" xmlns:s0="http://eliasen.eu.BizTalk.TestProject.InputSchema" xmlns:ns0="http://eliasen.eu.BizTalk.TestProject.OutputSchema" xmlns:userCSharp="http://schemas.microsoft.com/BizTalk/2003/userCSharp"> <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" /> <xsl:template match="/"> <xsl:apply-templates select="/s0:InputRoot" /> </xsl:template> <xsl:template match="/s0:InputRoot"> <xsl:variable name="var:v1" select="userCSharp:LogicalEq(string(qualifier/text()) , "Jan")" /> <ns0:OutputRoot> <xsl:if test="string($var:v1)='true'"> <xsl:variable name="var:v2" select="IfTrue/text()" /> <OutputField> <xsl:value-of select="$var:v2" /> </OutputField> </xsl:if> </ns0:OutputRoot> </xsl:template></xsl:stylesheet>
I have removed all the lines associated with the equals-functoid as that included three inline c# methods which are irrelevant. Anyway, as you can see, my functoid is not being called at all. Because I chose the ValueMapping category, the generated xslt assumes it is actually a built-in value mapping functoid and it totally overrules the logic inside the functoid.
So, this really came as a surprise to me... but well...it makes sense when you think about it, naturally. Some of the types of functoids just require logic that goes beyond the code inside a functoid.
So, the ValueMapping category just didn't work for me. Then I thought; "Oh, who cares?"? I will just use the String category instead, because those certainly do not have weird functionality around them... they get input and return a string as output, that is it. And the functoid will just appear in the String group in the toolbox in VS.NET.
That gave me a new headache, that was another surprise; You cannot connect the output of a logical functoid to the input of a string functoid. So... I was stuck.
One of my solutions would accept the output of a logical functoid as input, but my functoid logic was overridden. The other simply wouldn't accept the output of a logical functoid as input.
I have tried the following FunctoidCategories:
So, basically, I haven't been able to do it... for now. Either I cannot connect a logical functoid to my custom functoid, I get an error either at compile time or something goes wrong semantically at runtime.
I haven't given up 100% yet... but I must say, that the task has turned out to be a whole lot more difficult than I thought it would be.
Look out for a part 3 in this series... if it comes, I will have solved this issue
-- eliasen
Remember Me
a@href@title, b, blockquote@cite, em, i, strike, strong, sub, sup, u
Theme design by Jelle Druyts
Powered by: newtelligence dasBlog 2.3.9074.18820
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
© Copyright 2024, Jan Eliasen
E-mail