XsltFunctions.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / XmlUtils / System / Xml / Xsl / Runtime / XsltFunctions.cs / 1 / XsltFunctions.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
using System.IO; 
using System.Text;
using System.Reflection; 
using System.Diagnostics;
using System.ComponentModel;
using System.Globalization;
using System.Collections; 
using System.Collections.Generic;
using System.Collections.Specialized; 
using System.Xml.Schema; 
using System.Xml.XPath;
using System.Xml.Xsl.Xslt; 
using System.Runtime.InteropServices;

namespace System.Xml.Xsl.Runtime {
    using Res = System.Xml.Utils.Res; 

    [EditorBrowsable(EditorBrowsableState.Never)] 
    public static class XsltFunctions { 
        private static readonly CompareInfo compareInfo = CultureInfo.InvariantCulture.CompareInfo;
 

        //------------------------------------------------
        // Xslt/XPath functions
        //------------------------------------------------ 

        public static bool StartsWith(string s1, string s2) { 
            //return collation.IsPrefix(s1, s2); 
            return s1.Length >= s2.Length && string.CompareOrdinal(s1, 0, s2, 0, s2.Length) == 0;
        } 

        public static bool Contains(string s1, string s2) {
            //return collation.IndexOf(s1, s2) >= 0;
            return compareInfo.IndexOf(s1, s2, CompareOptions.Ordinal) >= 0; 
        }
 
        public static string SubstringBefore(string s1, string s2) { 
            if (s2.Length == 0) { return s2; }
            //int idx = collation.IndexOf(s1, s2); 
            int idx = compareInfo.IndexOf(s1, s2, CompareOptions.Ordinal);
            return (idx < 1) ? string.Empty : s1.Substring(0, idx);
        }
 
        public static string SubstringAfter(string s1, string s2) {
            if (s2.Length == 0) { return s1; } 
            //int idx = collation.IndexOf(s1, s2); 
            int idx = compareInfo.IndexOf(s1, s2, CompareOptions.Ordinal);
            return (idx < 0) ? string.Empty : s1.Substring(idx + s2.Length); 
        }

        public static string Substring(string value, double startIndex) {
            startIndex = Round(startIndex); 
            if (startIndex <= 0) {
                return value; 
            } else if (startIndex <= value.Length) { 
                return value.Substring((int)startIndex - 1);
            } else { 
                Debug.Assert(value.Length < startIndex || Double.IsNaN(startIndex));
                return string.Empty;
            }
        } 

        public static string Substring(string value, double startIndex, double length) { 
            startIndex = Round(startIndex) - 1;             // start index 
            if (startIndex >= value.Length) {
                return string.Empty; 
            }

            double endIndex = startIndex + Round(length);   // end index
            startIndex = (startIndex <= 0) ? 0 : startIndex; 

            if (startIndex < endIndex) { 
                if (endIndex > value.Length) { 
                    endIndex = value.Length;
                } 
                Debug.Assert(0 <= startIndex && startIndex <= endIndex && endIndex <= value.Length);
                return value.Substring((int)startIndex, (int)(endIndex - startIndex));
            } else {
                Debug.Assert(endIndex <= startIndex || Double.IsNaN(endIndex)); 
                return string.Empty;
            } 
        } 

        public static string NormalizeSpace(string value) { 
            XmlCharType xmlCharType = XmlCharType.Instance;
            StringBuilder sb = null;
            int idx, idxStart = 0, idxSpace = 0;
 
            for (idx = 0; idx < value.Length; idx++) {
                if (xmlCharType.IsWhiteSpace(value[idx])) { 
                    if (idx == idxStart) { 
                        // Previous character was a whitespace character, so discard this character
                        idxStart++; 
                    }
                    else if (value[idx] != ' ' || idxSpace == idx) {
                        // Space was previous character or this is a non-space character
                        if (sb == null) 
                            sb = new StringBuilder(value.Length);
                        else 
                            sb.Append(' '); 

                        // Copy non-space characters into string builder 
                        if (idxSpace == idx)
                            sb.Append(value, idxStart, idx - idxStart - 1);
                        else
                            sb.Append(value, idxStart, idx - idxStart); 

                        idxStart = idx + 1; 
                    } 
                    else {
                        // Single whitespace character doesn't cause normalization, but mark its position 
                        idxSpace = idx + 1;
                    }
                }
            } 

            if (sb == null) { 
                // Check for string that is entirely composed of whitespace 
                if (idxStart == idx) return string.Empty;
 
                // If string does not end with a space, then it must already be normalized
                if (idxStart == 0 && idxSpace != idx) return value;

                sb = new StringBuilder(value.Length); 
            }
            else if (idx != idxStart) { 
                sb.Append(' '); 
            }
 
            // Copy non-space characters into string builder
            if (idxSpace == idx)
                sb.Append(value, idxStart, idx - idxStart - 1);
            else 
                sb.Append(value, idxStart, idx - idxStart);
 
            return sb.ToString(); 
        }
 
        public static string Translate(string arg, string mapString, string transString) {
            if (mapString.Length == 0) {
                return arg;
            } 

            StringBuilder sb = new StringBuilder(arg.Length); 
 
            for (int i = 0; i < arg.Length; i++) {
                int index = mapString.IndexOf(arg[i]); 
                if (index < 0) {
                    // Keep the character
                    sb.Append(arg[i]);
                } else if (index < transString.Length) { 
                    // Replace the character
                    sb.Append(transString[index]); 
                } else { 
                    // Remove the character
                } 
            }
            return sb.ToString();
        }
 
        public static bool Lang(string value, XPathNavigator context) {
            string lang = context.XmlLang; 
 
            if (!lang.StartsWith(value, StringComparison.OrdinalIgnoreCase)) {
                return false; 
            }
            return (lang.Length == value.Length || lang[value.Length] == '-');
        }
 
        // Round value using XPath rounding rules (round towards positive infinity).
        // Values between -0.5 and -0.0 are rounded to -0.0 (negative zero). 
        public static double Round(double value) { 
            double temp = Math.Round(value);
            return (value - temp == 0.5) ? temp + 1 : temp; 
        }

        // Spec: http://www.w3.org/TR/xslt.html#function-system-property
        public static XPathItem SystemProperty(XmlQualifiedName name) { 
            if (name.Namespace == XmlReservedNs.NsXslt) {
                // "xsl:version" must return 1.0 as a number, see http://www.w3.org/TR/xslt20/#incompatility-without-schema 
                switch (name.Name) { 
                case "version"   :  return new XmlAtomicValue(XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.Double), 1.0);
                case "vendor"    :  return new XmlAtomicValue(XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String), "Microsoft"); 
                case "vendor-url":  return new XmlAtomicValue(XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String), "http://www.microsoft.com");
                }
            } else if (name.Namespace == XmlReservedNs.NsMsxsl && name.Name == "version") {
                // msxsl:version 
                return new XmlAtomicValue(XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String), typeof(XsltLibrary).Assembly.ImageRuntimeVersion);
            } 
            // If the property name is not recognized, return the empty string 
            return new XmlAtomicValue(XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String), string.Empty);
        } 


        //------------------------------------------------
        // Navigator functions 
        //------------------------------------------------
 
        public static string BaseUri(XPathNavigator navigator) { 
            return navigator.BaseURI;
        } 

        public static string OuterXml(XPathNavigator navigator) {
            RtfNavigator rtf = navigator as RtfNavigator;
            if (rtf == null) { 
                return navigator.OuterXml;
            } 
            StringBuilder sb = new StringBuilder(); 
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.OmitXmlDeclaration = true; 
            settings.ConformanceLevel = ConformanceLevel.Fragment;
            settings.CheckCharacters = false;
            XmlWriter xw = XmlWriter.Create(sb, settings);
            rtf.CopyToWriter(xw); 
            xw.Close();
            return sb.ToString(); 
        } 

 
        //------------------------------------------------
        // EXslt Functions
        //------------------------------------------------
 
        public static string EXslObjectType(IList value) {
            if (value.Count != 1) { 
                XsltLibrary.CheckXsltValue(value); 
                return "node-set";
            } 

            XPathItem item = value[0];
            if (item is RtfNavigator) {
                return "RTF"; 
            } else if (item.IsNode) {
                Debug.Assert(item is XPathNavigator); 
                return "node-set"; 
            }
 
            object o = item.TypedValue;
            if (o is string) {
                return "string";
            } else if (o is double) { 
                return "number";
            } else if (o is bool) { 
                return "boolean"; 
            } else {
                Debug.Fail("Unexpected type: " + o.GetType().ToString()); 
                return "external";
            }
        }
 

        //------------------------------------------------ 
        // Msxml Extension Functions 
        //------------------------------------------------
 
        public static double MSNumber(IList value) {
            XsltLibrary.CheckXsltValue(value);
            if (value.Count == 0) {
                return Double.NaN; 
            }
            XPathItem item = value[0]; 
 
            string stringValue;
 
            if (item.IsNode) {
                stringValue = item.Value;
            } else {
                Type itemType = item.ValueType; 
                if (itemType == XsltConvert.StringType) {
                    stringValue = item.Value; 
                } else if (itemType == XsltConvert.DoubleType) { 
                    return item.ValueAsDouble;
                } else { 
                    Debug.Assert(itemType == XsltConvert.BooleanType, "Unexpected type of atomic value " + itemType.ToString());
                    return item.ValueAsBoolean ? 1d : 0d;
                }
            } 

            Debug.Assert(stringValue != null); 
            double d; 
            if (XmlConvert.TryToDouble(stringValue, out d) != null) {
                d = double.NaN; 
            }
            return d;
        }
 
        // CharSet.Auto is needed to work on Windows 98 and Windows Me
        [DllImport("kernel32.dll", CharSet=CharSet.Auto)] 
        static extern int GetDateFormat(int locale, uint dwFlags, ref SystemTime sysTime, string format, StringBuilder sb, int sbSize); 

        [DllImport("kernel32.dll", CharSet=CharSet.Auto)] 
        static extern int GetTimeFormat(int locale, uint dwFlags, ref SystemTime sysTime, string format, StringBuilder sb, int sbSize);

        [StructLayout(LayoutKind.Sequential)]
        private struct SystemTime { 
            [MarshalAs(UnmanagedType.U2)] public ushort Year;
            [MarshalAs(UnmanagedType.U2)] public ushort Month; 
            [MarshalAs(UnmanagedType.U2)] public ushort DayOfWeek; 
            [MarshalAs(UnmanagedType.U2)] public ushort Day;
            [MarshalAs(UnmanagedType.U2)] public ushort Hour; 
            [MarshalAs(UnmanagedType.U2)] public ushort Minute;
            [MarshalAs(UnmanagedType.U2)] public ushort Second;
            [MarshalAs(UnmanagedType.U2)] public ushort Milliseconds;
 
            public SystemTime(DateTime dateTime) {
                this.Year         = (ushort)dateTime.Year; 
                this.Month        = (ushort)dateTime.Month; 
                this.DayOfWeek    = (ushort)dateTime.DayOfWeek;
                this.Day          = (ushort)dateTime.Day; 
                this.Hour         = (ushort)dateTime.Hour;
                this.Minute       = (ushort)dateTime.Minute;
                this.Second       = (ushort)dateTime.Second;
                this.Milliseconds = (ushort)dateTime.Millisecond; 
            }
        } 
 
        // string ms:format-date(string datetime[, string format[, string language]])
        // string ms:format-time(string datetime[, string format[, string language]]) 
        //
        // Format xsd:dateTime as a date/time string for a given language using a given format string.
        // * Datetime contains a lexical representation of xsd:dateTime. If datetime is not valid, the
        //   empty string is returned. 
        // * Format specifies a format string in the same way as for GetDateFormat/GetTimeFormat system
        //   functions. If format is the empty string or not passed, the default date/time format for the 
        //   given culture is used. 
        // * Language specifies a culture used for formatting. If language is the empty string or not
        //   passed, the current culture is used. If language is not recognized, a runtime error happens. 
        public static string MSFormatDateTime(string dateTime, string format, string lang, bool isDate) {
            try {
                int locale = GetCultureInfo(lang).LCID;
 
                XsdDateTime xdt;
                if (! XsdDateTime.TryParse(dateTime, XsdDateTimeFlags.AllXsd | XsdDateTimeFlags.XdrDateTime | XsdDateTimeFlags.XdrTimeNoTz, out xdt)) { 
                    return string.Empty; 
                }
                SystemTime st = new SystemTime(xdt.ToZulu()); 

                StringBuilder sb = new StringBuilder(format.Length + 16);

                // If format is the empty string or not specified, use the default format for the given locale 
                if (format.Length == 0) {
                    format = null; 
                } 
                if (isDate) {
                    int res = GetDateFormat(locale, 0, ref st, format, sb, sb.Capacity); 
                    if (res == 0) {
                        res = GetDateFormat(locale, 0, ref st, format, sb, 0);
                        if (res != 0) {
                            sb = new StringBuilder(res); 
                            res = GetDateFormat(locale, 0, ref st, format, sb, sb.Capacity);
                        } 
                    } 
                } else {
                    int res = GetTimeFormat(locale, 0, ref st, format, sb, sb.Capacity); 
                    if (res == 0) {
                        res = GetTimeFormat(locale, 0, ref st, format, sb, 0);
                        if (res != 0) {
                            sb = new StringBuilder(res); 
                            res = GetTimeFormat(locale, 0, ref st, format, sb, sb.Capacity);
                        } 
                    } 
                }
                return sb.ToString(); 
            } catch (ArgumentException) { // Operations with DateTime can throw this exception eventualy
                return string.Empty;
            }
        } 

        public static double MSStringCompare(string s1, string s2, string lang, string options) { 
            CultureInfo cultinfo = GetCultureInfo(lang); 
            CompareOptions opts = CompareOptions.None;
            bool upperFirst = false; 
            for (int idx = 0; idx < options.Length; idx++) {
                switch (options[idx]) {
                case 'i':
                    opts = CompareOptions.IgnoreCase | CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth; 
                    break;
                case 'u': 
                    upperFirst = true; 
                    break;
                default: 
                    upperFirst = true;
                    opts = CompareOptions.IgnoreCase;
                    break;
                } 
            }
 
            if (upperFirst) { 
                if (opts != CompareOptions.None) {
                    throw new XslTransformException(Res.Xslt_InvalidCompareOption, options); 
                }
                opts = CompareOptions.IgnoreCase;
            }
 
            int result = cultinfo.CompareInfo.Compare(s1, s2, opts);
            if (upperFirst && result == 0) { 
                result = -cultinfo.CompareInfo.Compare(s1, s2, CompareOptions.None); 
            }
            return result; 
        }

        public static string MSUtc(string dateTime) {
            XsdDateTime xdt; 
            DateTime dt;
            try { 
                if (! XsdDateTime.TryParse(dateTime, XsdDateTimeFlags.AllXsd | XsdDateTimeFlags.XdrDateTime | XsdDateTimeFlags.XdrTimeNoTz, out xdt)) { 
                    return string.Empty;
                } 
                dt = xdt.ToZulu();
            } catch (ArgumentException) { // Operations with DateTime can throw this exception eventualy
                return string.Empty;
            } 
            char[] text = "----------T00:00:00.000".ToCharArray();
            //            "YYYY-MM-DDTHH:NN:SS.III" 
            //             0         1         2 
            //             01234567890123456789012
            switch (xdt.TypeCode) { 
            case XmlTypeCode.DateTime:
                PrintDate(text, dt);
                PrintTime(text, dt);
                break; 
            case XmlTypeCode.Time:
                PrintTime(text, dt); 
                break; 
            case XmlTypeCode.Date:
                PrintDate(text, dt); 
                break;
            case XmlTypeCode.GYearMonth:
                PrintYear(  text, dt.Year);
                ShortToCharArray(text, 5, dt.Month); 
                break;
            case XmlTypeCode.GYear: 
                PrintYear(text, dt.Year); 
                break;
            case XmlTypeCode.GMonthDay: 
                ShortToCharArray(text, 5, dt.Month);
                ShortToCharArray(text, 8, dt.Day );
                break;
            case XmlTypeCode.GDay: 
                ShortToCharArray(text, 8, dt.Day );
                break; 
            case XmlTypeCode.GMonth: 
                ShortToCharArray(text, 5, dt.Month);
                break; 
            }
            return new String(text);
        }
 
        public static string MSLocalName(string name) {
            int colonOffset; 
            int len = ValidateNames.ParseQName(name, 0, out colonOffset); 

            if (len != name.Length) { 
                return string.Empty;
            }
            if (colonOffset == 0) {
                return name; 
            } else {
                return name.Substring(colonOffset + 1); 
            } 
        }
 
        public static string MSNamespaceUri(string name, XPathNavigator currentNode) {
            int colonOffset;
            int len = ValidateNames.ParseQName(name, 0, out colonOffset);
 
            if (len != name.Length) {
                return string.Empty; 
            } 
            string prefix = name.Substring(0, colonOffset);
            if (prefix == "xmlns") { 
                return string.Empty;
            }
            string ns = currentNode.LookupNamespace(prefix);
            if (ns != null) { 
                return ns;
            } 
            if (prefix == "xml") { 
                return XmlReservedNs.NsXml;
            } 
            return string.Empty;
        }

 
        //------------------------------------------------
        // Helper Functions 
        //------------------------------------------------ 

        private static CultureInfo GetCultureInfo(string lang) { 
            Debug.Assert(lang != null);
            if (lang.Length == 0) {
                return CultureInfo.CurrentCulture;
            } else { 
                try {
                    return new CultureInfo(lang); 
                } catch (System.ArgumentException) { 
                    throw new XslTransformException(Res.Xslt_InvalidLanguage, lang);
                } 
            }
        }

        private static void PrintDate(char[] text, DateTime dt) { 
            PrintYear(text, dt.Year);
            ShortToCharArray(text, 5, dt.Month); 
            ShortToCharArray(text, 8, dt.Day ); 
        }
 
        private static void PrintTime(char[] text, DateTime dt) {
            ShortToCharArray(text, 11, dt.Hour  );
            ShortToCharArray(text, 14, dt.Minute);
            ShortToCharArray(text, 17, dt.Second); 
            PrintMsec(text, dt.Millisecond);
        } 
 
        private static void PrintYear(char[] text, int value) {
            text[0] = (char) ((value / 1000) % 10 + '0'); 
            text[1] = (char) ((value / 100 ) % 10 + '0');
            text[2] = (char) ((value / 10  ) % 10 + '0');
            text[3] = (char) ((value / 1   ) % 10 + '0');
        } 

        private static void PrintMsec(char[] text, int value) { 
            if (value == 0) { 
                return;
            } 
            text[20] = (char) ((value / 100) % 10 + '0');
            text[21] = (char) ((value / 10 ) % 10 + '0');
            text[22] = (char) ((value / 1  ) % 10 + '0');
        } 

        private static void ShortToCharArray(char[] text, int start, int value) { 
            text[start    ] = (char)(value / 10 + '0'); 
            text[start + 1] = (char)(value % 10 + '0');
        } 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
using System.IO; 
using System.Text;
using System.Reflection; 
using System.Diagnostics;
using System.ComponentModel;
using System.Globalization;
using System.Collections; 
using System.Collections.Generic;
using System.Collections.Specialized; 
using System.Xml.Schema; 
using System.Xml.XPath;
using System.Xml.Xsl.Xslt; 
using System.Runtime.InteropServices;

namespace System.Xml.Xsl.Runtime {
    using Res = System.Xml.Utils.Res; 

    [EditorBrowsable(EditorBrowsableState.Never)] 
    public static class XsltFunctions { 
        private static readonly CompareInfo compareInfo = CultureInfo.InvariantCulture.CompareInfo;
 

        //------------------------------------------------
        // Xslt/XPath functions
        //------------------------------------------------ 

        public static bool StartsWith(string s1, string s2) { 
            //return collation.IsPrefix(s1, s2); 
            return s1.Length >= s2.Length && string.CompareOrdinal(s1, 0, s2, 0, s2.Length) == 0;
        } 

        public static bool Contains(string s1, string s2) {
            //return collation.IndexOf(s1, s2) >= 0;
            return compareInfo.IndexOf(s1, s2, CompareOptions.Ordinal) >= 0; 
        }
 
        public static string SubstringBefore(string s1, string s2) { 
            if (s2.Length == 0) { return s2; }
            //int idx = collation.IndexOf(s1, s2); 
            int idx = compareInfo.IndexOf(s1, s2, CompareOptions.Ordinal);
            return (idx < 1) ? string.Empty : s1.Substring(0, idx);
        }
 
        public static string SubstringAfter(string s1, string s2) {
            if (s2.Length == 0) { return s1; } 
            //int idx = collation.IndexOf(s1, s2); 
            int idx = compareInfo.IndexOf(s1, s2, CompareOptions.Ordinal);
            return (idx < 0) ? string.Empty : s1.Substring(idx + s2.Length); 
        }

        public static string Substring(string value, double startIndex) {
            startIndex = Round(startIndex); 
            if (startIndex <= 0) {
                return value; 
            } else if (startIndex <= value.Length) { 
                return value.Substring((int)startIndex - 1);
            } else { 
                Debug.Assert(value.Length < startIndex || Double.IsNaN(startIndex));
                return string.Empty;
            }
        } 

        public static string Substring(string value, double startIndex, double length) { 
            startIndex = Round(startIndex) - 1;             // start index 
            if (startIndex >= value.Length) {
                return string.Empty; 
            }

            double endIndex = startIndex + Round(length);   // end index
            startIndex = (startIndex <= 0) ? 0 : startIndex; 

            if (startIndex < endIndex) { 
                if (endIndex > value.Length) { 
                    endIndex = value.Length;
                } 
                Debug.Assert(0 <= startIndex && startIndex <= endIndex && endIndex <= value.Length);
                return value.Substring((int)startIndex, (int)(endIndex - startIndex));
            } else {
                Debug.Assert(endIndex <= startIndex || Double.IsNaN(endIndex)); 
                return string.Empty;
            } 
        } 

        public static string NormalizeSpace(string value) { 
            XmlCharType xmlCharType = XmlCharType.Instance;
            StringBuilder sb = null;
            int idx, idxStart = 0, idxSpace = 0;
 
            for (idx = 0; idx < value.Length; idx++) {
                if (xmlCharType.IsWhiteSpace(value[idx])) { 
                    if (idx == idxStart) { 
                        // Previous character was a whitespace character, so discard this character
                        idxStart++; 
                    }
                    else if (value[idx] != ' ' || idxSpace == idx) {
                        // Space was previous character or this is a non-space character
                        if (sb == null) 
                            sb = new StringBuilder(value.Length);
                        else 
                            sb.Append(' '); 

                        // Copy non-space characters into string builder 
                        if (idxSpace == idx)
                            sb.Append(value, idxStart, idx - idxStart - 1);
                        else
                            sb.Append(value, idxStart, idx - idxStart); 

                        idxStart = idx + 1; 
                    } 
                    else {
                        // Single whitespace character doesn't cause normalization, but mark its position 
                        idxSpace = idx + 1;
                    }
                }
            } 

            if (sb == null) { 
                // Check for string that is entirely composed of whitespace 
                if (idxStart == idx) return string.Empty;
 
                // If string does not end with a space, then it must already be normalized
                if (idxStart == 0 && idxSpace != idx) return value;

                sb = new StringBuilder(value.Length); 
            }
            else if (idx != idxStart) { 
                sb.Append(' '); 
            }
 
            // Copy non-space characters into string builder
            if (idxSpace == idx)
                sb.Append(value, idxStart, idx - idxStart - 1);
            else 
                sb.Append(value, idxStart, idx - idxStart);
 
            return sb.ToString(); 
        }
 
        public static string Translate(string arg, string mapString, string transString) {
            if (mapString.Length == 0) {
                return arg;
            } 

            StringBuilder sb = new StringBuilder(arg.Length); 
 
            for (int i = 0; i < arg.Length; i++) {
                int index = mapString.IndexOf(arg[i]); 
                if (index < 0) {
                    // Keep the character
                    sb.Append(arg[i]);
                } else if (index < transString.Length) { 
                    // Replace the character
                    sb.Append(transString[index]); 
                } else { 
                    // Remove the character
                } 
            }
            return sb.ToString();
        }
 
        public static bool Lang(string value, XPathNavigator context) {
            string lang = context.XmlLang; 
 
            if (!lang.StartsWith(value, StringComparison.OrdinalIgnoreCase)) {
                return false; 
            }
            return (lang.Length == value.Length || lang[value.Length] == '-');
        }
 
        // Round value using XPath rounding rules (round towards positive infinity).
        // Values between -0.5 and -0.0 are rounded to -0.0 (negative zero). 
        public static double Round(double value) { 
            double temp = Math.Round(value);
            return (value - temp == 0.5) ? temp + 1 : temp; 
        }

        // Spec: http://www.w3.org/TR/xslt.html#function-system-property
        public static XPathItem SystemProperty(XmlQualifiedName name) { 
            if (name.Namespace == XmlReservedNs.NsXslt) {
                // "xsl:version" must return 1.0 as a number, see http://www.w3.org/TR/xslt20/#incompatility-without-schema 
                switch (name.Name) { 
                case "version"   :  return new XmlAtomicValue(XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.Double), 1.0);
                case "vendor"    :  return new XmlAtomicValue(XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String), "Microsoft"); 
                case "vendor-url":  return new XmlAtomicValue(XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String), "http://www.microsoft.com");
                }
            } else if (name.Namespace == XmlReservedNs.NsMsxsl && name.Name == "version") {
                // msxsl:version 
                return new XmlAtomicValue(XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String), typeof(XsltLibrary).Assembly.ImageRuntimeVersion);
            } 
            // If the property name is not recognized, return the empty string 
            return new XmlAtomicValue(XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String), string.Empty);
        } 


        //------------------------------------------------
        // Navigator functions 
        //------------------------------------------------
 
        public static string BaseUri(XPathNavigator navigator) { 
            return navigator.BaseURI;
        } 

        public static string OuterXml(XPathNavigator navigator) {
            RtfNavigator rtf = navigator as RtfNavigator;
            if (rtf == null) { 
                return navigator.OuterXml;
            } 
            StringBuilder sb = new StringBuilder(); 
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.OmitXmlDeclaration = true; 
            settings.ConformanceLevel = ConformanceLevel.Fragment;
            settings.CheckCharacters = false;
            XmlWriter xw = XmlWriter.Create(sb, settings);
            rtf.CopyToWriter(xw); 
            xw.Close();
            return sb.ToString(); 
        } 

 
        //------------------------------------------------
        // EXslt Functions
        //------------------------------------------------
 
        public static string EXslObjectType(IList value) {
            if (value.Count != 1) { 
                XsltLibrary.CheckXsltValue(value); 
                return "node-set";
            } 

            XPathItem item = value[0];
            if (item is RtfNavigator) {
                return "RTF"; 
            } else if (item.IsNode) {
                Debug.Assert(item is XPathNavigator); 
                return "node-set"; 
            }
 
            object o = item.TypedValue;
            if (o is string) {
                return "string";
            } else if (o is double) { 
                return "number";
            } else if (o is bool) { 
                return "boolean"; 
            } else {
                Debug.Fail("Unexpected type: " + o.GetType().ToString()); 
                return "external";
            }
        }
 

        //------------------------------------------------ 
        // Msxml Extension Functions 
        //------------------------------------------------
 
        public static double MSNumber(IList value) {
            XsltLibrary.CheckXsltValue(value);
            if (value.Count == 0) {
                return Double.NaN; 
            }
            XPathItem item = value[0]; 
 
            string stringValue;
 
            if (item.IsNode) {
                stringValue = item.Value;
            } else {
                Type itemType = item.ValueType; 
                if (itemType == XsltConvert.StringType) {
                    stringValue = item.Value; 
                } else if (itemType == XsltConvert.DoubleType) { 
                    return item.ValueAsDouble;
                } else { 
                    Debug.Assert(itemType == XsltConvert.BooleanType, "Unexpected type of atomic value " + itemType.ToString());
                    return item.ValueAsBoolean ? 1d : 0d;
                }
            } 

            Debug.Assert(stringValue != null); 
            double d; 
            if (XmlConvert.TryToDouble(stringValue, out d) != null) {
                d = double.NaN; 
            }
            return d;
        }
 
        // CharSet.Auto is needed to work on Windows 98 and Windows Me
        [DllImport("kernel32.dll", CharSet=CharSet.Auto)] 
        static extern int GetDateFormat(int locale, uint dwFlags, ref SystemTime sysTime, string format, StringBuilder sb, int sbSize); 

        [DllImport("kernel32.dll", CharSet=CharSet.Auto)] 
        static extern int GetTimeFormat(int locale, uint dwFlags, ref SystemTime sysTime, string format, StringBuilder sb, int sbSize);

        [StructLayout(LayoutKind.Sequential)]
        private struct SystemTime { 
            [MarshalAs(UnmanagedType.U2)] public ushort Year;
            [MarshalAs(UnmanagedType.U2)] public ushort Month; 
            [MarshalAs(UnmanagedType.U2)] public ushort DayOfWeek; 
            [MarshalAs(UnmanagedType.U2)] public ushort Day;
            [MarshalAs(UnmanagedType.U2)] public ushort Hour; 
            [MarshalAs(UnmanagedType.U2)] public ushort Minute;
            [MarshalAs(UnmanagedType.U2)] public ushort Second;
            [MarshalAs(UnmanagedType.U2)] public ushort Milliseconds;
 
            public SystemTime(DateTime dateTime) {
                this.Year         = (ushort)dateTime.Year; 
                this.Month        = (ushort)dateTime.Month; 
                this.DayOfWeek    = (ushort)dateTime.DayOfWeek;
                this.Day          = (ushort)dateTime.Day; 
                this.Hour         = (ushort)dateTime.Hour;
                this.Minute       = (ushort)dateTime.Minute;
                this.Second       = (ushort)dateTime.Second;
                this.Milliseconds = (ushort)dateTime.Millisecond; 
            }
        } 
 
        // string ms:format-date(string datetime[, string format[, string language]])
        // string ms:format-time(string datetime[, string format[, string language]]) 
        //
        // Format xsd:dateTime as a date/time string for a given language using a given format string.
        // * Datetime contains a lexical representation of xsd:dateTime. If datetime is not valid, the
        //   empty string is returned. 
        // * Format specifies a format string in the same way as for GetDateFormat/GetTimeFormat system
        //   functions. If format is the empty string or not passed, the default date/time format for the 
        //   given culture is used. 
        // * Language specifies a culture used for formatting. If language is the empty string or not
        //   passed, the current culture is used. If language is not recognized, a runtime error happens. 
        public static string MSFormatDateTime(string dateTime, string format, string lang, bool isDate) {
            try {
                int locale = GetCultureInfo(lang).LCID;
 
                XsdDateTime xdt;
                if (! XsdDateTime.TryParse(dateTime, XsdDateTimeFlags.AllXsd | XsdDateTimeFlags.XdrDateTime | XsdDateTimeFlags.XdrTimeNoTz, out xdt)) { 
                    return string.Empty; 
                }
                SystemTime st = new SystemTime(xdt.ToZulu()); 

                StringBuilder sb = new StringBuilder(format.Length + 16);

                // If format is the empty string or not specified, use the default format for the given locale 
                if (format.Length == 0) {
                    format = null; 
                } 
                if (isDate) {
                    int res = GetDateFormat(locale, 0, ref st, format, sb, sb.Capacity); 
                    if (res == 0) {
                        res = GetDateFormat(locale, 0, ref st, format, sb, 0);
                        if (res != 0) {
                            sb = new StringBuilder(res); 
                            res = GetDateFormat(locale, 0, ref st, format, sb, sb.Capacity);
                        } 
                    } 
                } else {
                    int res = GetTimeFormat(locale, 0, ref st, format, sb, sb.Capacity); 
                    if (res == 0) {
                        res = GetTimeFormat(locale, 0, ref st, format, sb, 0);
                        if (res != 0) {
                            sb = new StringBuilder(res); 
                            res = GetTimeFormat(locale, 0, ref st, format, sb, sb.Capacity);
                        } 
                    } 
                }
                return sb.ToString(); 
            } catch (ArgumentException) { // Operations with DateTime can throw this exception eventualy
                return string.Empty;
            }
        } 

        public static double MSStringCompare(string s1, string s2, string lang, string options) { 
            CultureInfo cultinfo = GetCultureInfo(lang); 
            CompareOptions opts = CompareOptions.None;
            bool upperFirst = false; 
            for (int idx = 0; idx < options.Length; idx++) {
                switch (options[idx]) {
                case 'i':
                    opts = CompareOptions.IgnoreCase | CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth; 
                    break;
                case 'u': 
                    upperFirst = true; 
                    break;
                default: 
                    upperFirst = true;
                    opts = CompareOptions.IgnoreCase;
                    break;
                } 
            }
 
            if (upperFirst) { 
                if (opts != CompareOptions.None) {
                    throw new XslTransformException(Res.Xslt_InvalidCompareOption, options); 
                }
                opts = CompareOptions.IgnoreCase;
            }
 
            int result = cultinfo.CompareInfo.Compare(s1, s2, opts);
            if (upperFirst && result == 0) { 
                result = -cultinfo.CompareInfo.Compare(s1, s2, CompareOptions.None); 
            }
            return result; 
        }

        public static string MSUtc(string dateTime) {
            XsdDateTime xdt; 
            DateTime dt;
            try { 
                if (! XsdDateTime.TryParse(dateTime, XsdDateTimeFlags.AllXsd | XsdDateTimeFlags.XdrDateTime | XsdDateTimeFlags.XdrTimeNoTz, out xdt)) { 
                    return string.Empty;
                } 
                dt = xdt.ToZulu();
            } catch (ArgumentException) { // Operations with DateTime can throw this exception eventualy
                return string.Empty;
            } 
            char[] text = "----------T00:00:00.000".ToCharArray();
            //            "YYYY-MM-DDTHH:NN:SS.III" 
            //             0         1         2 
            //             01234567890123456789012
            switch (xdt.TypeCode) { 
            case XmlTypeCode.DateTime:
                PrintDate(text, dt);
                PrintTime(text, dt);
                break; 
            case XmlTypeCode.Time:
                PrintTime(text, dt); 
                break; 
            case XmlTypeCode.Date:
                PrintDate(text, dt); 
                break;
            case XmlTypeCode.GYearMonth:
                PrintYear(  text, dt.Year);
                ShortToCharArray(text, 5, dt.Month); 
                break;
            case XmlTypeCode.GYear: 
                PrintYear(text, dt.Year); 
                break;
            case XmlTypeCode.GMonthDay: 
                ShortToCharArray(text, 5, dt.Month);
                ShortToCharArray(text, 8, dt.Day );
                break;
            case XmlTypeCode.GDay: 
                ShortToCharArray(text, 8, dt.Day );
                break; 
            case XmlTypeCode.GMonth: 
                ShortToCharArray(text, 5, dt.Month);
                break; 
            }
            return new String(text);
        }
 
        public static string MSLocalName(string name) {
            int colonOffset; 
            int len = ValidateNames.ParseQName(name, 0, out colonOffset); 

            if (len != name.Length) { 
                return string.Empty;
            }
            if (colonOffset == 0) {
                return name; 
            } else {
                return name.Substring(colonOffset + 1); 
            } 
        }
 
        public static string MSNamespaceUri(string name, XPathNavigator currentNode) {
            int colonOffset;
            int len = ValidateNames.ParseQName(name, 0, out colonOffset);
 
            if (len != name.Length) {
                return string.Empty; 
            } 
            string prefix = name.Substring(0, colonOffset);
            if (prefix == "xmlns") { 
                return string.Empty;
            }
            string ns = currentNode.LookupNamespace(prefix);
            if (ns != null) { 
                return ns;
            } 
            if (prefix == "xml") { 
                return XmlReservedNs.NsXml;
            } 
            return string.Empty;
        }

 
        //------------------------------------------------
        // Helper Functions 
        //------------------------------------------------ 

        private static CultureInfo GetCultureInfo(string lang) { 
            Debug.Assert(lang != null);
            if (lang.Length == 0) {
                return CultureInfo.CurrentCulture;
            } else { 
                try {
                    return new CultureInfo(lang); 
                } catch (System.ArgumentException) { 
                    throw new XslTransformException(Res.Xslt_InvalidLanguage, lang);
                } 
            }
        }

        private static void PrintDate(char[] text, DateTime dt) { 
            PrintYear(text, dt.Year);
            ShortToCharArray(text, 5, dt.Month); 
            ShortToCharArray(text, 8, dt.Day ); 
        }
 
        private static void PrintTime(char[] text, DateTime dt) {
            ShortToCharArray(text, 11, dt.Hour  );
            ShortToCharArray(text, 14, dt.Minute);
            ShortToCharArray(text, 17, dt.Second); 
            PrintMsec(text, dt.Millisecond);
        } 
 
        private static void PrintYear(char[] text, int value) {
            text[0] = (char) ((value / 1000) % 10 + '0'); 
            text[1] = (char) ((value / 100 ) % 10 + '0');
            text[2] = (char) ((value / 10  ) % 10 + '0');
            text[3] = (char) ((value / 1   ) % 10 + '0');
        } 

        private static void PrintMsec(char[] text, int value) { 
            if (value == 0) { 
                return;
            } 
            text[20] = (char) ((value / 100) % 10 + '0');
            text[21] = (char) ((value / 10 ) % 10 + '0');
            text[22] = (char) ((value / 1  ) % 10 + '0');
        } 

        private static void ShortToCharArray(char[] text, int start, int value) { 
            text[start    ] = (char)(value / 10 + '0'); 
            text[start + 1] = (char)(value % 10 + '0');
        } 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK