Tech Blog

Understanding the BizTalk Mapper: Part 3 – String Functoids

The String Functoids are probably the most frequently used in maps (in my experience), mainly because they’re the most familiar to a procedural programmer (i.e. a C# or VB programmer). However because they all emit inline C#, they perform the slowest so if you want your maps to run faster you’re better off using the corresponding XSLT, or implementing the functionality you require in a separate assembly.

So for each functoid I’ve shown:

  1. Whether XSLT or C# is emitted
  2. Whether an XSLT equivalent exists
  3. The XSLT or C# emitted by the functoid
  4. Where C# is emitted, the equivalent XSLT to achieve the same functionality (in both
    XSLT v1.0 and v2.0)

Functoids covered in this category:

Lowercase String Left Trim
Size String Right
String Concatenate String Right Trim
String Extract Uppercase
String Find Common Code
String Left  

Note:

This is the third in a series of 13 posts about the BizTalk Mapper.
The other posts in this series are (links will become active as the posts become active):
Understanding
the BizTalk Mapper: Part 1 – Introduction


Understanding
the BizTalk Mapper: Part 2 – Functoids Overview


Understanding the BizTalk Mapper: Part 3 – String Functoids

Understanding
the BizTalk Mapper: Part 4 – Mathematical Functoids


Understanding
the BizTalk Mapper: Part 5 – Logical Functoids


Understanding
the BizTalk Mapper: Part 6 – Date/Time Functoids


Understanding
the BizTalk Mapper: Part 7 – Conversion Functoids


Understanding
the BizTalk Mapper: Part 8 – Scientific Functoids


Understanding
the BizTalk Mapper: Part 9 – Cumulative Functoids


Understanding
the BizTalk Mapper: Part 10 – Database Functoids


Understanding
the BizTalk Mapper: Part 11 – Advanced Functoids


Understanding
the BizTalk Mapper: Part 12 – Performance and Maintainability


Understanding
the BizTalk Mapper: Part 13 – Is the Mapper the best choice for Transformation in
BizTalk?

Download the complete series as a single Microsoft
Word document (1.2MB)
or Adobe
PDF document (620kb)
.

One thing to realise is that the majority of the default functoids emit inline C#
code – which is odd as quite a lot of the functionality can be performed using pure
XSLT.

String Functoids

 

Lowercase

 

 

Generates: C#

Has XSLT Equivalent: in 2.0 only, can use translate in
1.0

  Emitted Code:

public string StringLowerCase(string str)

{

    if (str
== null)


    {

        return “”;

    }

    return str.ToLower(System.Globalization.CultureInfo.InvariantCulture);

}
 

XSLT 1.0 Equivalent: translate(string, ‘ABCDEFGHIJKLMNOPQRSTUVWXYZ’,
‘abcdefghijklmnopqrstuvwxyz’)

 

XSLT 2.0 Equivalent: lower-case(string)

 

 

Size

 

 

Generates: C#

Has XSLT Equivalent: in 1.0 and 2.0

  Emitted Code:

public int StringSize(string str)

{

    if (str
== null)


    {

        return 0;

    }

    return str.Length;

}
 

XSLT 1.0 Equivalent: string-length(string)

 

XSLT 2.0 Equivalent: string-length(string)

 

 

String Concatenate

 

 

Generates: C#

Has XSLT Equivalent: in 1.0 and 2.0

  Emitted Code:

Note: there will be one overload per unique number of parameters.

Here we show an example with one input parameter, and three input parameters

public string StringConcat(string param0)

{

    return param0;

}

 

public string StringConcat(string param0, string param1, string param2)

{

    return param0
+ param1 + param2;


}
 

XSLT 1.0 Equivalent: concat(string, string,
…)

 

XSLT 2.0 Equivalent: concat(string, string,
…)

 

 

String Extract

 

 

Generates: C#

Has XSLT Equivalent: in 1.0 and 2.0

  Emitted Code:

public string StringSubstring(string str, string left, string right)

{

    string retval
= “”;


    double dleft
= 0;


    double dright
= 0;


    if (str
!= null && IsNumeric(left, ref dleft)
&& IsNumeric(right, ref dright))


    {

        int lt
= (int)dleft;


        int rt
= (int)dright;


       
lt–; rt–;


        if (lt
>= 0 && rt >= lt && lt < str.Length)


       
{


            if (rt
< str.Length)


           
{


               
retval = str.Substring(lt, rt – lt + 1);


           
}


            else

           
{


               
retval = str.Substring(lt, str.Length – lt);


           
}


       
}


    }

    return retval;

}
 

XSLT 1.0 Equivalent: substring(string, number, number)

  XSLT 2.0 Equivalent: substring(string, number, number)

Note: the substring() function takes a length as
its last parameter, rather than the position used by the String Extract functoid.
Additionally, there is an overload of substring() which takes two parameters,
as well as additional substring-before() and substring-after() functions.
 

 

String Find

 

 

Generates: C#

Has XSLT Equivalent: No

  Emitted Code:

public int StringFind(string str, string strFind)

{

    if (str
== null || strFind == null ||
strFind == “”)


    {

        return 0;

    }

    return (str.IndexOf(strFind)
+ 1);


}
 

XSLT 1.0 Equivalent: (none)

  XSLT 2.0 Equivalent: (none)

Note: The method is usually used as an input to the String
Extract
functoid – however, if using the XSLT substring() function then
an index is not needed, so the fact that there is no XSLT equivalent should not cause
any issues.
 

 

String Left

 

 

Generates: C#

Has XSLT Equivalent: in 1.0 and 2.0

  Emitted Code:

public string StringLeft(string str, string count)

{

    string retval
= “”;


    double d
= 0;


    if (str
!= null && IsNumeric(count, ref d))


    {

        int i
= (int)d;


        if (i
> 0)


       
{


            if (i
<= str.Length)


           
{


               
retval = str.Substring(0, i);


           
}


       
    else


           
{


               
retval = str;


           
}


       
}


    }

    return retval;

}
 

XSLT 1.0 Equivalent: substring(string, number)

 

XSLT 2.0 Equivalent: substring(string, number)

 

 

String Left Trim

 

 

Generates: C#

Has XSLT Equivalent: No

  Emitted Code:

public string StringTrimLeft(string str)

{

    if (str
== null)


    {

        return “”;

    }

    return str.TrimStart(null);

}
 

XSLT 1.0 Equivalent: (none)

  XSLT 2.0 Equivalent: (none)

Note: the closest equivalent is normalize-space()
which trims leading and trailing spaces, and also replaces any groups of spaces in
a string with a single space.
 

 

String Right

 

 

Generates: C#

Has XSLT Equivalent: No

  Emitted Code:

public string StringRight(string str, string count)

{

    string retval
= “”;


    double d
= 0;


    if (str
!= null && IsNumeric(count, ref d))


    {

        int i
= (int)d;


        if (i
> 0)


       
{


            if (i
<= str.Length)


           
{


               
retval = str.Substring(str.Length – i);


           
}


            else

           
{


               
retval = str;


           
}


       
}


    }

    return retval;

}
 

XSLT 1.0 Equivalent: (none)

  XSLT 2.0 Equivalent: (none)

Note: although there is no single XSLT function for this,
the same result can be achieved through use of the string-length() and substring()
functions.


e.g. substring(string, string-length(string) – number)
 

 

String Right Trim

 

 

Generates: C#

Has XSLT Equivalent: No

  Emitted Code:

public string StringTrimRight(string str)

{

    if (str
== null)


    {

        return “”;

    }

    return str.TrimEnd(null);

}
 

XSLT 1.0 Equivalent: (none)

  XSLT 2.0 Equivalent: (none)

Note: the closest equivalent is normalize-space()
which trims leading and trailing spaces, and also replaces any groups of spaces in
a string with a single space.
 

 

Uppercase

 

 

Generates: C#

Has XSLT Equivalent: in 2.0 Only, can use translate in
1.0

  Emitted Code:

public string StringUpperCase(string str)

{

    if (str
== null)


    {

        return “”;

    }

    return str.ToUpper(System.Globalization.CultureInfo.InvariantCulture);

}
 

XSLT 1.0 Equivalent: translate(string, ‘abcdefghijklmnopqrstuvwxyz’,
‘ABCDEFGHIJKLMNOPQRSTUVWXYZ’)

 

XSLT 2.0 Equivalent: upper-case(string)

 
  Common Code

(this is common code used by all the string functoids)
  public bool IsNumeric(string val)

{

    if (val
== null)


    {

        return false;

    }

    double d
= 0;


    return Double.TryParse(val,
System.Globalization.NumberStyles.AllowThousands
| System.Globalization.NumberStyles.Float,
System.Globalization.CultureInfo.InvariantCulture, out d);


}

 

public bool IsNumeric(string val, ref double d)

{

    if (val
== null)


    {

        return false;

    }

    return Double.TryParse(val,
System.Globalization.NumberStyles.AllowThousands
| System.Globalization.NumberStyles.Float,
System.Globalization.CultureInfo.InvariantCulture, out d);


}

Back to Tech Blog