Skip to content
News and insights
BizTalk Mapper

Understanding the BizTalk Mapper: Part 4 – Mathematical Functoids

Mathematics is not a strong point of XSLT. XSLT v1.0 has very poor mathematic support, whilst XSLT v2.0 has better support, but only by a small amount. Therefore most of the functoids in this category can only be implemented in C#.

So if you want to perform a complicated mathematical function (i.e. anything more
than addition or subtraction!) you’re better off using one of these functoids, or
an external assembly.

Once again, inline C# isn’t the fastest, but given a choice between a slow function
and no function, you might not have a choice.

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:

Absolute Value Modulo
Addition Multiplication
Division Round
Integer Square Root
Maximum Value Subtraction
Minimum Value Common Code

Note:

This is the fourth 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)
.

Mathematical Functoids
Absolute Value
Generates: C# Has XSLT Equivalent: in 2.0 only
Emitted Code:public string MathAbs(string val)

{

    string retval
= “”;

    double d
= 0;

    if (IsNumeric(val, ref d))

    {

        double abs
= Math.Abs(d);


retval = abs.ToString(System.Globalization.CultureInfo.InvariantCulture);

    }

    return retval;

}

XSLT 1.0 Equivalent: (none)
XSLT 2.0 Equivalent: abs(number)Note:
In XSLT 1.0, you can achieve the desired result through use of an XSLT template and
the xsl:when statement (i.e. check if number is < 0).
Addition
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 two input parameters.

public string MathAdd(string param0, string param1)

{

    System.Collections.ArrayList listValues
= new System.Collections.ArrayList();

    listValues.Add(param0);

    listValues.Add(param1);

    double ret
= 0;

    foreach (string obj in listValues)

    {

        double d
= 0;

        if (IsNumeric(obj, ref d))


{


ret += d;


}

        else


{

            return “”;


}

    }

    return ret.ToString(System.Globalization.CultureInfo.InvariantCulture);

}

XSLT 1.0 Equivalent: Use the “+” operator e.g. ((number + number)
+ number) or the sum(number, number, …) function
XSLT 2.0 Equivalent: Use the “+” operator e.g. ((number + number)
+ number) or the sum(number, number, …) function
Division
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 two input parameters.

public string MathDivide(string val1, string val2)

{

    string retval
= “”;

    double d1
= 0;

    double d2
= 0;

    if (IsNumeric(val1, ref d1)
&& IsNumeric(val2, ref d2))

    {

        if (d2
!= 0)


{

            double ret
= d1 / d2;


retval = ret.ToString(System.Globalization.CultureInfo.InvariantCulture);


}

    }

    return retval;

}

XSLT 1.0 Equivalent: Use the div operator e.g. number div number
XSLT 2.0 Equivalent: Use the div operator e.g. number div number
Integer
Generates: C# Has XSLT Equivalent: No
Emitted Code:public string MathInt(string val)

{

    string retval
= “”;

    double d
= 0;

    if (IsNumeric(val, ref d))

    {

        try


{

            int i
= Convert.ToInt32(d, System.Globalization.CultureInfo.InvariantCulture);

            if (i
> d)


{


i = i – 1;

            }


retval = i.ToString(System.Globalization.CultureInfo.InvariantCulture);


}

        catch (Exception)


{


}

    }

    return retval;

}

XSLT 1.0 Equivalent: (none)
XSLT 2.0 Equivalent: (none)Note: the floor() function will give an equivalent
result e.g. floor(3.90) will give ‘3’.
Maximum Value
Generates: C# Has XSLT Equivalent: in 2.0 only
Emitted Code:public string MathMax(string param0, string param1)

{

    double max
= Double.NegativeInfinity;

    System.Collections.ArrayList listValues
= new System.Collections.ArrayList();

    listValues.Add(param0);

    listValues.Add(param1);

    foreach (string obj in listValues)

    {

        double d
= 0;

        if (IsNumeric(obj, ref d))

        {


max = (d >= max) ? d : max;

        }

        else


{

            return “”;


}

    }

    if (Double.NegativeInfinity
== max)

    {

        return “”;

    }

    else

    {

        return max.ToString(System.Globalization.CultureInfo.InvariantCulture);

    }

}

XSLT 1.0 Equivalent: (none)
XSLT 2.0 Equivalent: Use the max(number, number,
…) functionNote: in XSLT 1.0 you could write a fairly complicated XPath
statement to achieve this
Minimum Value
Generates: C# Has XSLT Equivalent: in 2.0 only
Emitted Code:public string MathMin(string param0, string param1)

{

    double min
= Double.PositiveInfinity;

    System.Collections.ArrayList listValues
= new System.Collections.ArrayList();

    listValues.Add(param0);

    listValues.Add(param1);

    foreach (string obj in listValues)

    {

        double d
= 0;

        if (IsNumeric(obj, ref d))

        {


min = (d < min) ? d : min;

        }

        else


{

            return “”;


}

    }

    if (Double.PositiveInfinity
== min)

    {

        return “”;

    }

    else

    {

        return min.ToString(System.Globalization.CultureInfo.InvariantCulture);

    }

}

XSLT 1.0 Equivalent: (none)
XSLT 2.0 Equivalent: Use the min(number, number,
…) functionNote: in XSLT 1.0 you could write a fairly complicated XPath
statement to achieve this
Modulo
Generates: C# Has XSLT Equivalent: in 1.0 and 2.0
Emitted Code:public string MathMod(string val, string denominator)

{

    string retval
= “”;

    double v
= 0;

    double d
= 0;

    if (IsNumeric(val, ref v)
&& IsNumeric(denominator, ref d))

    {

        if (d
!= 0)


{


retval = Convert.ToString(v % d, System.Globalization.CultureInfo.InvariantCulture);


}

    }

    return retval;

}

XSLT 1.0 Equivalent: Use the “mod” operator e.g. number mod number
XSLT 2.0 Equivalent: Use the “mod” operator e.g. number mod number
Multiplication
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 two input parameters.

public string MathMultiply(string param0, string param1)

{

    System.Collections.ArrayList listValues
= new System.Collections.ArrayList();

    listValues.Add(param0);

    listValues.Add(param1);

    double ret
= 1;

    bool first
= true;

    foreach (string obj in listValues)

    {

        double d
= 0;

        if (IsNumeric(obj, ref d))


{

            if (first)


{


first = false;


ret = d;


}

            else


{


ret *= d;


}


}

        else


{

            return “”;


}

    }

    return ret.ToString(System.Globalization.CultureInfo.InvariantCulture);

}

XSLT 1.0 Equivalent: Use the “*” operator e.g. ((number * number)
* number)
XSLT 2.0 Equivalent: Use the “*” operator e.g. ((number * number)
* number)
Round
Generates: C# Has XSLT Equivalent: in 1.0 and 2.0
Emitted Code:public string MathRound(string val)

{

    return MathRound(val, “0”);

}

 

public string MathRound(string val, string decimals)

{

    string retval
= “”;

    double v
= 0;

    double db
= 0;

    if (IsNumeric(val, ref v)
&& IsNumeric(decimals, ref db))

    {

        try


{

            int d
= (int)db;

            double ret
= Math.Round(v, d);


retval = ret.ToString(System.Globalization.CultureInfo.InvariantCulture);


}

        catch (Exception)


{


}

    }

    return retval;

}

XSLT 1.0 Equivalent: round(number)
XSLT 2.0 Equivalent: round(number)Note: the XSLT round() function does not take a second
parameter – all number are rounded to 0 decimal places. You can achieve rounding to
x dp’s through use of the format-number(number, string) function:e.g. format-number(3.55555, ‘#.00’) – but be aware that rounding in this way
might not always give the result you’re looking for e.g. 9.2850 rounds to 9.28 using format-number()
(although this can be coded around in XSLT).
Square Root
Generates: C# Has XSLT Equivalent: No
Emitted Code:public string MathSqrt(string val)

{

    string retval
= “”;

    double d
= 0;

    if (IsNumeric(val, ref d))

    {

        if (d
>= 0)


{

            double ret
= Math.Sqrt(d);


retval = ret.ToString(System.Globalization.CultureInfo.InvariantCulture);


}

    }

    return retval;

}

XSLT 1.0 Equivalent: (none)
XSLT 2.0 Equivalent: (none)Note: A square-root can be calculated using an XSLT template
– see here for
an example.
Subtraction
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 two input parameters.

public string MathSubtract(string param0, string param1)

{

    System.Collections.ArrayList listValues
= new System.Collections.ArrayList();

    listValues.Add(param0);

    listValues.Add(param1);

    double ret
= 0;

    bool first
= true;

    foreach (string obj in listValues)

    {

        if (first)


{


first = false;

            double d
= 0;

            if (IsNumeric(obj, ref d))


{


ret = d;


}

            else


{

                return “”;


}


}

        else


{

            double d
= 0;

            if (IsNumeric(obj, ref d))


{


ret -= d;


}

            else


{

                return “”;


}


}

    }

    return ret.ToString(System.Globalization.CultureInfo.InvariantCulture);

}

XSLT 1.0 Equivalent: Use the “-” operator e.g. ((numbernumber)
number)
XSLT 2.0 Equivalent: Use the “-” operator e.g. ((numbernumber)
number)
Common Code(this is common code used by all the mathematical 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);

}

Share this article:

Back To Top