Saturday, 15 November 2008

Hi all

I have often wondered why the built-in functoids doesn't encompass an If-Then-Else functoid. The Value Mapping functoid only has an If-Then-part and not the Else-part.

This is the first of two blog posts. This post will explore how to solve the issue with the built-in functionality of BizTalk. The next post will be about creating a custom functoid to do the job instead and the issues that come with this task.

So, using the built-in functionality:

Imagine this input schema:

IfThenElseInputSchema

And imagine this output schema:

IfThenElseOutputSchema

My goal, now is to create a map that will map the value of the "ifJan" element to the destination IF the "qualifier" element equals the word "Jan" and otherwise the value of the "ifNotJan" element should be mapped.

So basically, given this input:

<ns0:IfThenElseInput xmlns:ns0="http://IfThenElse.IfThenElseInput">
  <qualifier>Jan</qualifier>
  <ifJan>ifJan</ifJan>
  <ifNotJan>ifNotJan</ifNotJan>
</ns0:IfThenElseInput>

I want this output:

<ns0:IfThenElseOutput xmlns:ns0="http://IfThenElse.IfThenElseOutput">
  <field>ifJan</field>
</ns0:IfThenElseOutput>

And given this input:

<ns0:IfThenElseInput xmlns:ns0="http://IfThenElse.IfThenElseInput">
  <qualifier>NotJan</qualifier>
  <ifJan>ifJan</ifJan>
  <ifNotJan>ifNotJan</ifNotJan>
</ns0:IfThenElseInput>

I want this output:

<ns0:IfThenElseOutput xmlns:ns0="http://IfThenElse.IfThenElseOutput">
  <field>ifNotJan</field>
</ns0:IfThenElseOutput>

Using a map and the built-in functoids, that would look like this:

 IfThenElseMap_Functoids

Basically, you need one value mapping functoid for each possible value to pass on, and a logical functoid for each value as well, to use in the value mapping functoid. The "String Concatenate" functoid is just my way of returning the string to use for the qualifier - in this case: "Jan".

You can also do it using one scripting functoid like this:

IfThenElseMap_Scripting_XSLT

where the scripting functoid is an "Inline XSLT Call Template" scripting type, and the script looks likes this:

<xsl:template name="IfThenElse">
  <xsl:param name="qualifier" />
  <xsl:param name="ifJan" />
  <xsl:param name="ifNotJan" />
  <xsl:element name="field">
    <xsl:choose>
      <xsl:when test="$qualifier='Jan'">
        <xsl:value-of select="$ifJan" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$ifNotJan" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:element>
</xsl:template>

Now... IF my good friend Henrik Badsberg is reading this, then by now he is screaming: "USE A BLOODY C# SCRIPTING FUNCTOID!!!!!" :-)

This, naturally is also an option:

IfThenElseMap_Scripting_CSharp

with an "Inline C#" script containing this script:

public string IfThenElse(string qualifier, string ifJan, string ifNotJan)
{
  if (qualifier == "Jan")
    return ifJan;
  else
    return ifNotJan;
}

Both scripting solutions can be altered to accept the output of a logical functoid as the first input. Just change the string "Jan" to "true" in the scripts, and change the name of the parameter if you want.

Now then... I am not a big fan of either of these three options. Generally, I avoid scripting functoids when I can because it is difficult for a new developer to know what is happening when he opens the map because he will have to open up all scripting functoids and find out (and remember) what they do. Also, I am not really a big fan of the first solution either. First of all, there are too many functoids, and it can messy if this solution is needed several times in a map. Secondly, you get a warning every time you compile, because you have two inputs to one element.

You can find my project with the three working maps here.

In my next post, I will look into creating a custom functoid that does the job and I can tell you right now; That isn't as easy as I had imagined...

--
eliasen

Saturday, 15 November 2008 21:49:40 (Romance Standard Time, UTC+01:00)  #    Comments [0]  | 

Theme design by Jelle Druyts