XPathQilFactory.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / XmlUtils / System / Xml / Xsl / XPath / XPathQilFactory.cs / 1 / XPathQilFactory.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
using System.Diagnostics; 
using System.Xml.Schema;
using System.Xml.Xsl.Qil; 
using System.Xml.Xsl.Runtime;

namespace System.Xml.Xsl.XPath {
    using Res   = System.Xml.Utils.Res; 
    using T     = XmlQueryTypeFactory;
 
    internal class XPathQilFactory : QilPatternFactory { 

        public XPathQilFactory(QilFactory f, bool debug) : base(f, debug) { 
        }

        // Helper methods used in addition to QilPatternFactory's ones
 
        public QilNode Error(string res, QilNode args) {
            return Error(InvokeFormatMessage(String(res), args)); 
        } 

        public QilNode Error(ISourceLineInfo lineInfo, string res, params string[] args) { 
            return Error(String(XslLoadException.CreateMessage(lineInfo, res, args)));
        }

        public QilIterator FirstNode(QilNode n) { 
            CheckNodeSet(n);
            QilIterator i = For(DocOrderDistinct(n)); 
            return For(Filter(i, Eq(PositionOf(i), Int32(1)))); 
        }
 
        public bool IsAnyType(QilNode n) {
            XmlQueryType xt = n.XmlType;
            bool result = !(xt.IsStrict || xt.IsNode);
            Debug.Assert(result == (xt.TypeCode == XmlTypeCode.Item || xt.TypeCode == XmlTypeCode.AnyAtomicType), "What else can it be?"); 
            return result;
        } 
 
        [Conditional("DEBUG")]
        public void CheckAny(QilNode n) { 
            Debug.Assert(n != null && IsAnyType(n), "Must be of 'any' type");
        }

        [Conditional("DEBUG")] 
        public void CheckNode(QilNode n) {
            Debug.Assert(n != null && n.XmlType.IsSingleton && n.XmlType.IsNode, "Must be a singleton node"); 
        } 

        [Conditional("DEBUG")] 
        public void CheckNodeSet(QilNode n) {
            Debug.Assert(n != null && n.XmlType.IsNode, "Must be a node-set");
        }
 
        [Conditional("DEBUG")]
        public void CheckNodeNotRtf(QilNode n) { 
            Debug.Assert(n != null && n.XmlType.IsSingleton && n.XmlType.IsNode && n.XmlType.IsNotRtf, "Must be a singleton node and not an Rtf"); 
        }
 
        [Conditional("DEBUG")]
        public void CheckString(QilNode n) {
            Debug.Assert(n != null && n.XmlType.IsSubtypeOf(T.StringX), "Must be a singleton string");
        } 

        [Conditional("DEBUG")] 
        public void CheckStringS(QilNode n) { 
            Debug.Assert(n != null && n.XmlType.IsSubtypeOf(T.StringXS), "Must be a sequence of strings");
        } 

        [Conditional("DEBUG")]
        public void CheckDouble(QilNode n) {
            Debug.Assert(n != null && n.XmlType.IsSubtypeOf(T.DoubleX), "Must be a singleton Double"); 
        }
 
        [Conditional("DEBUG")] 
        public void CheckBool(QilNode n) {
            Debug.Assert(n != null && n.XmlType.IsSubtypeOf(T.BooleanX), "Must be a singleton Bool"); 
        }

        // Return true if inferred type of the given expression is never a subtype of T.NodeS
        public bool CannotBeNodeSet(QilNode n) { 
            XmlQueryType xt = n.XmlType;
            // Do not report compile error if n is a VarPar, whose inferred type forbids nodes (SQLBUDT 339398) 
            return xt.IsAtomicValue && !xt.IsEmpty && !(n is QilIterator); 
        }
 
        public QilNode SafeDocOrderDistinct(QilNode n) {
            XmlQueryType xt = n.XmlType;

            if (xt.MaybeMany) { 
                if (xt.IsNode && xt.IsNotRtf) {
                    // node-set 
                    return DocOrderDistinct(n); 
                } else if (!xt.IsAtomicValue) {
                    QilIterator i; 
                    return Loop(i = Let(n),
                        Conditional(Gt(Length(i), Int32(1)),
                            DocOrderDistinct(TypeAssert(i, T.NodeNotRtfS)),
                            i 
                        )
                    ); 
                } 
            }
 
            return n;
        }

        public QilNode InvokeFormatMessage(QilNode res, QilNode args) { 
            CheckString(res);
            CheckStringS(args); 
            return XsltInvokeEarlyBound(QName("format-message"), 
                XsltMethods.FormatMessage, T.StringX, new QilNode[] { res, args }
            ); 
        }

        #region Comparisons
        public QilNode InvokeEqualityOperator(QilNodeType op, QilNode left, QilNode right) { 
            Debug.Assert(op == QilNodeType.Eq || op == QilNodeType.Ne);
            double opCode; 
            left  = TypeAssert(left,  T.ItemS); 
            right = TypeAssert(right, T.ItemS);
 
            switch (op) {
            case QilNodeType.Eq:    opCode = (double)XsltLibrary.ComparisonOperator.Eq; break;
            default:                opCode = (double)XsltLibrary.ComparisonOperator.Ne; break;
            } 
            return XsltInvokeEarlyBound(QName("EqualityOperator"),
                XsltMethods.EqualityOperator, T.BooleanX, new QilNode[] { Double(opCode), left, right } 
            ); 
        }
 
        public QilNode InvokeRelationalOperator(QilNodeType op, QilNode left, QilNode right) {
            Debug.Assert(op == QilNodeType.Lt || op == QilNodeType.Le || op == QilNodeType.Gt || op == QilNodeType.Ge);
            double opCode;
            left  = TypeAssert(left,  T.ItemS); 
            right = TypeAssert(right, T.ItemS);
 
            switch (op) { 
            case QilNodeType.Lt:    opCode = (double)XsltLibrary.ComparisonOperator.Lt; break;
            case QilNodeType.Le:    opCode = (double)XsltLibrary.ComparisonOperator.Le; break; 
            case QilNodeType.Gt:    opCode = (double)XsltLibrary.ComparisonOperator.Gt; break;
            default:                opCode = (double)XsltLibrary.ComparisonOperator.Ge; break;
            }
            return XsltInvokeEarlyBound(QName("RelationalOperator"), 
                XsltMethods.RelationalOperator, T.BooleanX, new QilNode[] { Double(opCode), left, right }
            ); 
        } 
        #endregion
 
        #region Type Conversions
        [Conditional("DEBUG")]
        private void ExpectAny(QilNode n) {
            Debug.Assert(IsAnyType(n), "Unexpected expression type: " + n.XmlType.ToString()); 
        }
 
        public QilNode ConvertToType(XmlTypeCode requiredType, QilNode n) { 
            switch (requiredType) {
            case XmlTypeCode.String     : return ConvertToString(n); 
            case XmlTypeCode.Double     : return ConvertToNumber(n);
            case XmlTypeCode.Boolean    : return ConvertToBoolean(n);
            case XmlTypeCode.Node       : return EnsureNodeSet(n);
            case XmlTypeCode.Item       : return n; 
            default                     : Debug.Fail("Unexpected XmlTypeCode: " + requiredType); return null;
            } 
        } 

        // XPath spec $4.2, string() 
        public QilNode ConvertToString(QilNode n) {
            switch (n.XmlType.TypeCode) {
            case XmlTypeCode.Boolean :
                return ( 
                    n.NodeType == QilNodeType.True  ? (QilNode) String("true") :
                    n.NodeType == QilNodeType.False ? (QilNode) String("false") : 
                    /*default: */                     (QilNode) Conditional(n, String("true"), String("false")) 
                );
            case XmlTypeCode.Double : 
                return (n.NodeType == QilNodeType.LiteralDouble
                    ? (QilNode) String(XPathConvert.DoubleToString((double)(QilLiteral)n))
                    : (QilNode) XsltConvert(n, T.StringX)
                ); 
            case XmlTypeCode.String :
                return n; 
            default : 
                if (n.XmlType.IsNode) {
                    return XPathNodeValue(SafeDocOrderDistinct(n)); 
                }

                ExpectAny(n);
                return XsltConvert(n, T.StringX); 
            }
        } 
 
        // XPath spec $4.3, boolean()
        public QilNode ConvertToBoolean(QilNode n) { 
            switch (n.XmlType.TypeCode) {
            case XmlTypeCode.Boolean :
                return n;
            case XmlTypeCode.Double : 
                // (x < 0 || 0 < x)  ==  (x != 0) && !Double.IsNaN(x)
                QilIterator i; 
                return (n.NodeType == QilNodeType.LiteralDouble 
                    ? Boolean((double)(QilLiteral)n < 0 || 0 < (double)(QilLiteral)n)
                    : Loop(i = Let(n), Or(Lt(i, Double(0)), Lt(Double(0), i))) 
                );
            case XmlTypeCode.String :
                return (n.NodeType == QilNodeType.LiteralString
                    ? Boolean(((string)(QilLiteral)n).Length != 0) 
                    : Ne(StrLength(n), Int32(0))
                ); 
            default: 
                if (n.XmlType.IsNode) {
                    return Not(IsEmpty(n)); 
                }

                ExpectAny(n);
                return XsltConvert(n, T.BooleanX); 
            }
        } 
 
        // XPath spec $4.4, number()
        public QilNode ConvertToNumber(QilNode n) { 
            switch (n.XmlType.TypeCode) {
            case XmlTypeCode.Boolean :
                return (
                    n.NodeType == QilNodeType.True  ? (QilNode) Double(1) : 
                    n.NodeType == QilNodeType.False ? (QilNode) Double(0) :
                    /*default: */                 (QilNode) Conditional(n, Double(1), Double(0)) 
                ); 
            case XmlTypeCode.Double :
                return n; 
            case XmlTypeCode.String :
                return XsltConvert(n, T.DoubleX);
            default:
                if (n.XmlType.IsNode) { 
                    return XsltConvert(XPathNodeValue(SafeDocOrderDistinct(n)), T.DoubleX);
                } 
 
                ExpectAny(n);
                return XsltConvert(n, T.DoubleX); 
            }
        }

        public QilNode ConvertToNode(QilNode n) { 
            if (n.XmlType.IsNode && n.XmlType.IsNotRtf && n.XmlType.IsSingleton) {
                return n; 
            } 
            return XsltConvert(n, T.NodeNotRtf);
        } 

        public QilNode ConvertToNodeSet(QilNode n) {
            if (n.XmlType.IsNode && n.XmlType.IsNotRtf) {
                return n; 
            }
 
            return XsltConvert(n, T.NodeNotRtfS); 
        }
 
        public QilNode EnsureNodeSet(QilNode n) {
            if (n.XmlType.IsNode && n.XmlType.IsNotRtf) {
                return n;
            } 
            if (CannotBeNodeSet(n)) {
                throw new XPathCompileException(Res.XPath_NodeSetExpected); 
            } 

            // Ensure it is not an Rtf at runtime 
            return InvokeEnsureNodeSet(n);
        }

        public QilNode InvokeEnsureNodeSet(QilNode n) { 
            return XsltInvokeEarlyBound(QName("ensure-node-set"),
                XsltMethods.EnsureNodeSet, T.NodeDodS, new QilNode[] { n } 
            ); 
        }
        #endregion 

        #region Other XPath Functions
        public QilNode Id(QilNode context, QilNode id) {
            CheckNodeNotRtf(context); 

            if (id.XmlType.IsSingleton) { 
                return Deref(context, ConvertToString(id)); 
            }
 
            QilIterator i;
            return Loop(i = For(id), Deref(context, ConvertToString(i)));
        }
 
        public QilNode InvokeStartsWith(QilNode str1, QilNode str2) {
            CheckString(str1); 
            CheckString(str2); 
            return XsltInvokeEarlyBound(QName("starts-with"),
                XsltMethods.StartsWith, T.BooleanX, new QilNode[] { str1, str2 } 
            );
        }

        public QilNode InvokeContains(QilNode str1, QilNode str2) { 
            CheckString(str1);
            CheckString(str2); 
            return XsltInvokeEarlyBound(QName("contains"), 
                XsltMethods.Contains, T.BooleanX, new QilNode[] { str1, str2 }
            ); 
        }

        public QilNode InvokeSubstringBefore(QilNode str1, QilNode str2) {
            CheckString(str1); 
            CheckString(str2);
            return XsltInvokeEarlyBound(QName("substring-before"), 
                XsltMethods.SubstringBefore, T.StringX, new QilNode[] { str1, str2 } 
            );
        } 

        public QilNode InvokeSubstringAfter(QilNode str1, QilNode str2) {
            CheckString(str1);
            CheckString(str2); 
            return XsltInvokeEarlyBound(QName("substring-after"),
                XsltMethods.SubstringAfter, T.StringX, new QilNode[] { str1, str2 } 
            ); 
        }
 
        public QilNode InvokeSubstring(QilNode str, QilNode start) {
            CheckString(str);
            CheckDouble(start);
            return XsltInvokeEarlyBound(QName("substring"), 
                XsltMethods.Substring2, T.StringX, new QilNode[] { str, start }
            ); 
        } 

        public QilNode InvokeSubstring(QilNode str, QilNode start, QilNode length) { 
            CheckString(str);
            CheckDouble(start);
            CheckDouble(length);
            return XsltInvokeEarlyBound(QName("substring"), 
                XsltMethods.Substring3, T.StringX, new QilNode[] { str, start, length }
            ); 
        } 

        public QilNode InvokeNormalizeSpace(QilNode str) { 
            CheckString(str);
            return XsltInvokeEarlyBound(QName("normalize-space"),
                XsltMethods.NormalizeSpace, T.StringX, new QilNode[] { str }
            ); 
        }
 
        public QilNode InvokeTranslate(QilNode str1, QilNode str2, QilNode str3) { 
            CheckString(str1);
            CheckString(str2); 
            CheckString(str3);
            return XsltInvokeEarlyBound(QName("translate"),
                XsltMethods.Translate, T.StringX, new QilNode[] { str1, str2, str3 }
            ); 
        }
 
        public QilNode InvokeLang(QilNode lang, QilNode context) { 
            CheckString(lang);
            CheckNodeNotRtf(context); 
            return XsltInvokeEarlyBound(QName("lang"),
                XsltMethods.Lang, T.BooleanX, new QilNode[] { lang, context }
            );
        } 

        public QilNode InvokeFloor(QilNode value) { 
            CheckDouble(value); 
            return XsltInvokeEarlyBound(QName("floor"),
                XsltMethods.Floor, T.DoubleX, new QilNode[] { value } 
            );
        }

        public QilNode InvokeCeiling(QilNode value) { 
            CheckDouble(value);
            return XsltInvokeEarlyBound(QName("ceiling"), 
                XsltMethods.Ceiling, T.DoubleX, new QilNode[] { value } 
            );
        } 

        public QilNode InvokeRound(QilNode value) {
            CheckDouble(value);
            return XsltInvokeEarlyBound(QName("round"), 
                XsltMethods.Round, T.DoubleX, new QilNode[] { value }
            ); 
        } 
        #endregion
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
using System.Diagnostics; 
using System.Xml.Schema;
using System.Xml.Xsl.Qil; 
using System.Xml.Xsl.Runtime;

namespace System.Xml.Xsl.XPath {
    using Res   = System.Xml.Utils.Res; 
    using T     = XmlQueryTypeFactory;
 
    internal class XPathQilFactory : QilPatternFactory { 

        public XPathQilFactory(QilFactory f, bool debug) : base(f, debug) { 
        }

        // Helper methods used in addition to QilPatternFactory's ones
 
        public QilNode Error(string res, QilNode args) {
            return Error(InvokeFormatMessage(String(res), args)); 
        } 

        public QilNode Error(ISourceLineInfo lineInfo, string res, params string[] args) { 
            return Error(String(XslLoadException.CreateMessage(lineInfo, res, args)));
        }

        public QilIterator FirstNode(QilNode n) { 
            CheckNodeSet(n);
            QilIterator i = For(DocOrderDistinct(n)); 
            return For(Filter(i, Eq(PositionOf(i), Int32(1)))); 
        }
 
        public bool IsAnyType(QilNode n) {
            XmlQueryType xt = n.XmlType;
            bool result = !(xt.IsStrict || xt.IsNode);
            Debug.Assert(result == (xt.TypeCode == XmlTypeCode.Item || xt.TypeCode == XmlTypeCode.AnyAtomicType), "What else can it be?"); 
            return result;
        } 
 
        [Conditional("DEBUG")]
        public void CheckAny(QilNode n) { 
            Debug.Assert(n != null && IsAnyType(n), "Must be of 'any' type");
        }

        [Conditional("DEBUG")] 
        public void CheckNode(QilNode n) {
            Debug.Assert(n != null && n.XmlType.IsSingleton && n.XmlType.IsNode, "Must be a singleton node"); 
        } 

        [Conditional("DEBUG")] 
        public void CheckNodeSet(QilNode n) {
            Debug.Assert(n != null && n.XmlType.IsNode, "Must be a node-set");
        }
 
        [Conditional("DEBUG")]
        public void CheckNodeNotRtf(QilNode n) { 
            Debug.Assert(n != null && n.XmlType.IsSingleton && n.XmlType.IsNode && n.XmlType.IsNotRtf, "Must be a singleton node and not an Rtf"); 
        }
 
        [Conditional("DEBUG")]
        public void CheckString(QilNode n) {
            Debug.Assert(n != null && n.XmlType.IsSubtypeOf(T.StringX), "Must be a singleton string");
        } 

        [Conditional("DEBUG")] 
        public void CheckStringS(QilNode n) { 
            Debug.Assert(n != null && n.XmlType.IsSubtypeOf(T.StringXS), "Must be a sequence of strings");
        } 

        [Conditional("DEBUG")]
        public void CheckDouble(QilNode n) {
            Debug.Assert(n != null && n.XmlType.IsSubtypeOf(T.DoubleX), "Must be a singleton Double"); 
        }
 
        [Conditional("DEBUG")] 
        public void CheckBool(QilNode n) {
            Debug.Assert(n != null && n.XmlType.IsSubtypeOf(T.BooleanX), "Must be a singleton Bool"); 
        }

        // Return true if inferred type of the given expression is never a subtype of T.NodeS
        public bool CannotBeNodeSet(QilNode n) { 
            XmlQueryType xt = n.XmlType;
            // Do not report compile error if n is a VarPar, whose inferred type forbids nodes (SQLBUDT 339398) 
            return xt.IsAtomicValue && !xt.IsEmpty && !(n is QilIterator); 
        }
 
        public QilNode SafeDocOrderDistinct(QilNode n) {
            XmlQueryType xt = n.XmlType;

            if (xt.MaybeMany) { 
                if (xt.IsNode && xt.IsNotRtf) {
                    // node-set 
                    return DocOrderDistinct(n); 
                } else if (!xt.IsAtomicValue) {
                    QilIterator i; 
                    return Loop(i = Let(n),
                        Conditional(Gt(Length(i), Int32(1)),
                            DocOrderDistinct(TypeAssert(i, T.NodeNotRtfS)),
                            i 
                        )
                    ); 
                } 
            }
 
            return n;
        }

        public QilNode InvokeFormatMessage(QilNode res, QilNode args) { 
            CheckString(res);
            CheckStringS(args); 
            return XsltInvokeEarlyBound(QName("format-message"), 
                XsltMethods.FormatMessage, T.StringX, new QilNode[] { res, args }
            ); 
        }

        #region Comparisons
        public QilNode InvokeEqualityOperator(QilNodeType op, QilNode left, QilNode right) { 
            Debug.Assert(op == QilNodeType.Eq || op == QilNodeType.Ne);
            double opCode; 
            left  = TypeAssert(left,  T.ItemS); 
            right = TypeAssert(right, T.ItemS);
 
            switch (op) {
            case QilNodeType.Eq:    opCode = (double)XsltLibrary.ComparisonOperator.Eq; break;
            default:                opCode = (double)XsltLibrary.ComparisonOperator.Ne; break;
            } 
            return XsltInvokeEarlyBound(QName("EqualityOperator"),
                XsltMethods.EqualityOperator, T.BooleanX, new QilNode[] { Double(opCode), left, right } 
            ); 
        }
 
        public QilNode InvokeRelationalOperator(QilNodeType op, QilNode left, QilNode right) {
            Debug.Assert(op == QilNodeType.Lt || op == QilNodeType.Le || op == QilNodeType.Gt || op == QilNodeType.Ge);
            double opCode;
            left  = TypeAssert(left,  T.ItemS); 
            right = TypeAssert(right, T.ItemS);
 
            switch (op) { 
            case QilNodeType.Lt:    opCode = (double)XsltLibrary.ComparisonOperator.Lt; break;
            case QilNodeType.Le:    opCode = (double)XsltLibrary.ComparisonOperator.Le; break; 
            case QilNodeType.Gt:    opCode = (double)XsltLibrary.ComparisonOperator.Gt; break;
            default:                opCode = (double)XsltLibrary.ComparisonOperator.Ge; break;
            }
            return XsltInvokeEarlyBound(QName("RelationalOperator"), 
                XsltMethods.RelationalOperator, T.BooleanX, new QilNode[] { Double(opCode), left, right }
            ); 
        } 
        #endregion
 
        #region Type Conversions
        [Conditional("DEBUG")]
        private void ExpectAny(QilNode n) {
            Debug.Assert(IsAnyType(n), "Unexpected expression type: " + n.XmlType.ToString()); 
        }
 
        public QilNode ConvertToType(XmlTypeCode requiredType, QilNode n) { 
            switch (requiredType) {
            case XmlTypeCode.String     : return ConvertToString(n); 
            case XmlTypeCode.Double     : return ConvertToNumber(n);
            case XmlTypeCode.Boolean    : return ConvertToBoolean(n);
            case XmlTypeCode.Node       : return EnsureNodeSet(n);
            case XmlTypeCode.Item       : return n; 
            default                     : Debug.Fail("Unexpected XmlTypeCode: " + requiredType); return null;
            } 
        } 

        // XPath spec $4.2, string() 
        public QilNode ConvertToString(QilNode n) {
            switch (n.XmlType.TypeCode) {
            case XmlTypeCode.Boolean :
                return ( 
                    n.NodeType == QilNodeType.True  ? (QilNode) String("true") :
                    n.NodeType == QilNodeType.False ? (QilNode) String("false") : 
                    /*default: */                     (QilNode) Conditional(n, String("true"), String("false")) 
                );
            case XmlTypeCode.Double : 
                return (n.NodeType == QilNodeType.LiteralDouble
                    ? (QilNode) String(XPathConvert.DoubleToString((double)(QilLiteral)n))
                    : (QilNode) XsltConvert(n, T.StringX)
                ); 
            case XmlTypeCode.String :
                return n; 
            default : 
                if (n.XmlType.IsNode) {
                    return XPathNodeValue(SafeDocOrderDistinct(n)); 
                }

                ExpectAny(n);
                return XsltConvert(n, T.StringX); 
            }
        } 
 
        // XPath spec $4.3, boolean()
        public QilNode ConvertToBoolean(QilNode n) { 
            switch (n.XmlType.TypeCode) {
            case XmlTypeCode.Boolean :
                return n;
            case XmlTypeCode.Double : 
                // (x < 0 || 0 < x)  ==  (x != 0) && !Double.IsNaN(x)
                QilIterator i; 
                return (n.NodeType == QilNodeType.LiteralDouble 
                    ? Boolean((double)(QilLiteral)n < 0 || 0 < (double)(QilLiteral)n)
                    : Loop(i = Let(n), Or(Lt(i, Double(0)), Lt(Double(0), i))) 
                );
            case XmlTypeCode.String :
                return (n.NodeType == QilNodeType.LiteralString
                    ? Boolean(((string)(QilLiteral)n).Length != 0) 
                    : Ne(StrLength(n), Int32(0))
                ); 
            default: 
                if (n.XmlType.IsNode) {
                    return Not(IsEmpty(n)); 
                }

                ExpectAny(n);
                return XsltConvert(n, T.BooleanX); 
            }
        } 
 
        // XPath spec $4.4, number()
        public QilNode ConvertToNumber(QilNode n) { 
            switch (n.XmlType.TypeCode) {
            case XmlTypeCode.Boolean :
                return (
                    n.NodeType == QilNodeType.True  ? (QilNode) Double(1) : 
                    n.NodeType == QilNodeType.False ? (QilNode) Double(0) :
                    /*default: */                 (QilNode) Conditional(n, Double(1), Double(0)) 
                ); 
            case XmlTypeCode.Double :
                return n; 
            case XmlTypeCode.String :
                return XsltConvert(n, T.DoubleX);
            default:
                if (n.XmlType.IsNode) { 
                    return XsltConvert(XPathNodeValue(SafeDocOrderDistinct(n)), T.DoubleX);
                } 
 
                ExpectAny(n);
                return XsltConvert(n, T.DoubleX); 
            }
        }

        public QilNode ConvertToNode(QilNode n) { 
            if (n.XmlType.IsNode && n.XmlType.IsNotRtf && n.XmlType.IsSingleton) {
                return n; 
            } 
            return XsltConvert(n, T.NodeNotRtf);
        } 

        public QilNode ConvertToNodeSet(QilNode n) {
            if (n.XmlType.IsNode && n.XmlType.IsNotRtf) {
                return n; 
            }
 
            return XsltConvert(n, T.NodeNotRtfS); 
        }
 
        public QilNode EnsureNodeSet(QilNode n) {
            if (n.XmlType.IsNode && n.XmlType.IsNotRtf) {
                return n;
            } 
            if (CannotBeNodeSet(n)) {
                throw new XPathCompileException(Res.XPath_NodeSetExpected); 
            } 

            // Ensure it is not an Rtf at runtime 
            return InvokeEnsureNodeSet(n);
        }

        public QilNode InvokeEnsureNodeSet(QilNode n) { 
            return XsltInvokeEarlyBound(QName("ensure-node-set"),
                XsltMethods.EnsureNodeSet, T.NodeDodS, new QilNode[] { n } 
            ); 
        }
        #endregion 

        #region Other XPath Functions
        public QilNode Id(QilNode context, QilNode id) {
            CheckNodeNotRtf(context); 

            if (id.XmlType.IsSingleton) { 
                return Deref(context, ConvertToString(id)); 
            }
 
            QilIterator i;
            return Loop(i = For(id), Deref(context, ConvertToString(i)));
        }
 
        public QilNode InvokeStartsWith(QilNode str1, QilNode str2) {
            CheckString(str1); 
            CheckString(str2); 
            return XsltInvokeEarlyBound(QName("starts-with"),
                XsltMethods.StartsWith, T.BooleanX, new QilNode[] { str1, str2 } 
            );
        }

        public QilNode InvokeContains(QilNode str1, QilNode str2) { 
            CheckString(str1);
            CheckString(str2); 
            return XsltInvokeEarlyBound(QName("contains"), 
                XsltMethods.Contains, T.BooleanX, new QilNode[] { str1, str2 }
            ); 
        }

        public QilNode InvokeSubstringBefore(QilNode str1, QilNode str2) {
            CheckString(str1); 
            CheckString(str2);
            return XsltInvokeEarlyBound(QName("substring-before"), 
                XsltMethods.SubstringBefore, T.StringX, new QilNode[] { str1, str2 } 
            );
        } 

        public QilNode InvokeSubstringAfter(QilNode str1, QilNode str2) {
            CheckString(str1);
            CheckString(str2); 
            return XsltInvokeEarlyBound(QName("substring-after"),
                XsltMethods.SubstringAfter, T.StringX, new QilNode[] { str1, str2 } 
            ); 
        }
 
        public QilNode InvokeSubstring(QilNode str, QilNode start) {
            CheckString(str);
            CheckDouble(start);
            return XsltInvokeEarlyBound(QName("substring"), 
                XsltMethods.Substring2, T.StringX, new QilNode[] { str, start }
            ); 
        } 

        public QilNode InvokeSubstring(QilNode str, QilNode start, QilNode length) { 
            CheckString(str);
            CheckDouble(start);
            CheckDouble(length);
            return XsltInvokeEarlyBound(QName("substring"), 
                XsltMethods.Substring3, T.StringX, new QilNode[] { str, start, length }
            ); 
        } 

        public QilNode InvokeNormalizeSpace(QilNode str) { 
            CheckString(str);
            return XsltInvokeEarlyBound(QName("normalize-space"),
                XsltMethods.NormalizeSpace, T.StringX, new QilNode[] { str }
            ); 
        }
 
        public QilNode InvokeTranslate(QilNode str1, QilNode str2, QilNode str3) { 
            CheckString(str1);
            CheckString(str2); 
            CheckString(str3);
            return XsltInvokeEarlyBound(QName("translate"),
                XsltMethods.Translate, T.StringX, new QilNode[] { str1, str2, str3 }
            ); 
        }
 
        public QilNode InvokeLang(QilNode lang, QilNode context) { 
            CheckString(lang);
            CheckNodeNotRtf(context); 
            return XsltInvokeEarlyBound(QName("lang"),
                XsltMethods.Lang, T.BooleanX, new QilNode[] { lang, context }
            );
        } 

        public QilNode InvokeFloor(QilNode value) { 
            CheckDouble(value); 
            return XsltInvokeEarlyBound(QName("floor"),
                XsltMethods.Floor, T.DoubleX, new QilNode[] { value } 
            );
        }

        public QilNode InvokeCeiling(QilNode value) { 
            CheckDouble(value);
            return XsltInvokeEarlyBound(QName("ceiling"), 
                XsltMethods.Ceiling, T.DoubleX, new QilNode[] { value } 
            );
        } 

        public QilNode InvokeRound(QilNode value) {
            CheckDouble(value);
            return XsltInvokeEarlyBound(QName("round"), 
                XsltMethods.Round, T.DoubleX, new QilNode[] { value }
            ); 
        } 
        #endregion
    } 
}

// 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