Whenever I’ve looked at the XSLT generated by a map I’ve always been confused by the amount of inline C# generated by these functoids.
After the String Functoids I’d say that these are the next most widely used and yet
all but one of them has an XSLT v1.0 equivalent!
The code emitted for “Logical Equal” always makes me laugh – 12 lines of C# code can
be replaced by… (wait for it)… one “=” symbol!

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:

Equal Logical Existence
Greater Than Logical NOT
Greater Than or Equal To Logical Numeric
IsNil Logical OR
Less Than Logical String
Less Than or Equal To Not Equal
Logical Date Common Code

Note:

This is the fifth 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?

When all of the above have been posted, the entire series will
be downloadable as a single Microsoft Word document, or Adobe PDF file.

Logical Functoids

 

Equal

 

 

Generates: C#

Has XSLT Equivalent: in 1.0 and 2.0

  Emitted Code:

public bool LogicalEq(string val1, string val2)

{

    bool ret
= false;


    double d1
= 0;


    double d2
= 0;


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


    {

       
ret = d1 == d2;


    }

    else

    {

       
ret = String.Compare(val1, val2, StringComparison.Ordinal) == 0;


    }

    return ret;

}
 

XSLT 1.0 Equivalent: Use the “=” operator e.g. value = value

  XSLT 2.0 Equivalent: Use the “=” operator e.g. value = value

Note: Both the C# version and the XSLT version
will perform a case-sensitive comparison.
 

 

Greater Than

 

 

Generates: C#

Has XSLT Equivalent: in 1.0 and 2.0

  Emitted Code:

public bool LogicalGt(string val1, string val2)

{

    bool ret
= false;


    double d1
= 0;


    double d2
= 0;


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


    {

       
ret = d1 > d2;


    }

    else

    {

       
ret = String.Compare(val1, val2, StringComparison.Ordinal) > 0;


    }

    return ret;

}
 

XSLT 1.0 Equivalent: Use the “>” operator e.g. value > value

 

XSLT 2.0 Equivalent: Use the “>” operator e.g. value > value

 

 

Greater Than
or Equal To

 

 

Generates: C#

Has XSLT Equivalent: in 1.0 and 2.0

  Emitted Code:

public bool LogicalGte(string val1, string val2)

{

    bool ret
= false;


    double d1
= 0;


    double d2
= 0;


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


    {

       
ret = d1 >= d2;


    }

    else

    {

       
ret = String.Compare(val1, val2, StringComparison.Ordinal) >= 0;


    }

    return ret;

}
 

XSLT 1.0 Equivalent: Use the “>=” operator e.g. value >= value

 

XSLT 2.0 Equivalent: Use the “>=” operator e.g. value >= value

 

 

IsNil

 

 

Generates: XSLT

Has XSLT Equivalent: N/A

  Emitted Code:

string(node/@xsi:nil) = ‘true’
 

 

Less Than

 

 

Generates: C#

Has XSLT Equivalent: in 1.0 and 2.0

  Emitted Code:

public bool LogicalLt(string val1, string val2)

{

    bool ret
= false;


    double d1
= 0;


    double d2
= 0;


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


    {

       
ret = d1 < d2;


    }

    else

    {

       
ret = String.Compare(val1, val2, StringComparison.Ordinal) < 0;


    }

    return ret;

}
 

XSLT 1.0 Equivalent: Use the “<” operator e.g. value < value

 

XSLT 2.0 Equivalent: Use the “<” operator e.g. value < value

 

 

Less Than or Equal
To

 

 

Generates: C#

Has XSLT Equivalent: in 1.0 and 2.0

  Emitted Code:

public bool LogicalLte(string val1, string val2)

{

    bool ret
= false;


    double d1
= 0;


    double d2
= 0;


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


    {

       
ret = d1 <= d2;


    }

    else

    {

       
ret = String.Compare(val1, val2, StringComparison.Ordinal) <= 0;


    }

    return ret;

}
 

XSLT 1.0 Equivalent: Use the “<=” operator e.g. value <= value

 

XSLT 2.0 Equivalent: Use the “<=” operator e.g. value <= value

 

 

Logical AND

 

 

Generates: C#

Has XSLT Equivalent: in 1.0 and 2.0

  Emitted Code:

public bool LogicalAnd(string param0, string param1)

{

    return ValToBool(param0)
&& ValToBool(param1);


    return false;

}
 

XSLT 1.0 Equivalent: Use the “and” operator e.g. expression and expression

 

XSLT 2.0 Equivalent: Use the “and” operator e.g. expression and expression

 

 

Logical Date

 

 

Generates: C#

Has XSLT Equivalent: No

  Emitted Code:

public bool LogicalIsDate(string val)

{

    return IsDate(val);

}
 

XSLT 1.0 Equivalent: (none)

  XSLT 2.0 Equivalent: (none)

Note: an XPath expression could be created using the dateTime
function, but would require parsing out separate date/time portions. There are other
implementations available on the internet, but none of them are trivial.


XPath 1.0 has no native DateTime functionality built in.
 

 

Logical Existence

 

 

Generates: C#

Has XSLT Equivalent: in 1.0 and 2.0

  Emitted Code:

public bool LogicalExistence(bool val)

{

    return val;

}

Note: The above method may seem a bit strange, but it makes
sense if you understand that you test for existence of a node in XSLT by using the boolean() function,
and passing a node (or any sort of value).


The XSLT generated by the Logical Existence functoid wraps the boolean() function
round the value passed to the LogicalExistence method like this:
userC#:LogicalExistence(boolean(@name)) (where
@name was an attribute that we connected to the
Logical
Existence
functoid).
 

XSLT 1.0 Equivalent: boolean(node)

 

XSLT 2.0 Equivalent: boolean(node)

 

 

Logical NOT

 

 

Generates: C#

Has XSLT Equivalent: in 1.0 and 2.0

  Emitted Code:

public bool LogicalNot(string val)

{

    return !ValToBool(val);

}
 

XSLT 1.0 Equivalent: not(expression)

 

XSLT 2.0 Equivalent: not(expression)

 

 

Logical Numeric

 

Generates: C#

Has XSLT Equivalent: No

  Emitted Code:

public bool LogicalIsNumeric(string val)

{

    return IsNumeric(val);

}
 

XSLT 1.0 Equivalent: (none)

  XSLT 2.0 Equivalent: (none)

Note: You can achieve this through use of a statement such
as: string(number(value)) != ‘
NaN

Or in XPath 2.0 using a statement such as: value castable as xs:decimal
 

 

 

Logical OR

 

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 bool LogicalOr(string param0, string param1)

{

    return ValToBool(param0)
|| ValToBool(param1);


    return false;

}
 

XSLT 1.0 Equivalent: Use the “or” operator e.g. ((expression or expression)
or expression)

 

XSLT 2.0 Equivalent: Use the “or” operator e.g. ((expression or expression)
or expression)

   

 

Logical String

 

Generates: C#

Has XSLT Equivalent: No

  Emitted Code:

public bool LogicalIsString(string val)

{

    return (val
!= null && val != “”);


}
 

XSLT 1.0 Equivalent: (none)

  XSLT 2.0 Equivalent: (none)

Note: the same thing can be achieved with an XPath expression.
 

 

 

Not Equal

 

Generates: C#

Has XSLT Equivalent: in 1.0 and 2.0

  Emitted Code:

public bool LogicalNe(string val1, string val2)

{

    bool ret
= false;


    double d1
= 0;


    double d2
= 0;


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


    {

       
ret = d1 != d2;


    }

    else

    {

       
ret = String.Compare(val1, val2, StringComparison.Ordinal) != 0;


    }

    return ret;

}
 

XSLT 1.0 Equivalent: Use the “!=” operator e.g. (value != value)

  XSLT 2.0 Equivalent: Use the “!=” operator e.g. (value != value)
 

 

  Common Code

(this is common code used by all the logical 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);


}

 

public bool IsDate(string val)

{

    bool retval
= true;


    try

    {

       
DateTime dt = Convert.ToDateTime(val, System.Globalization.CultureInfo.InvariantCulture);


    }

    catch (Exception)

    {

       
retval = false;


    }

    return retval;

}

 

public bool ValToBool(string val)

{

    if (val
!= null)


    {

        if (string.Compare(val, bool.TrueString,
StringComparison.OrdinalIgnoreCase) == 0)


        {

            return true;

       
}


        if (string.Compare(val, bool.FalseString,
StringComparison.OrdinalIgnoreCase) == 0)


       
{


            return false;

       
}


       
val = val.Trim();


        if (string.Compare(val, bool.TrueString,
StringComparison.OrdinalIgnoreCase) == 0)


       
{


            return true;

       
}


        if (string.Compare(val, bool.FalseString,
StringComparison.OrdinalIgnoreCase) == 0)


       
{


            return false;

       
}


        double d
= 0;


        if (IsNumeric(val, ref d))

       
{


            return (d
> 0);


       
}


    }

    return false;

}