CompiledXpathExpr.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Xml / System / Xml / XPath / Internal / CompiledXpathExpr.cs / 1305376 / CompiledXpathExpr.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
namespace MS.Internal.Xml.XPath { 
    using System;
    using System.Xml; 
    using System.Xml.XPath;
    using System.Diagnostics;
    using System.Globalization;
    using System.Collections; 
    using System.Xml.Xsl;
 
    internal class CompiledXpathExpr : XPathExpression { 
        Query query;
        string expr; 
        bool needContext;

        internal CompiledXpathExpr(Query query, string expression, bool needContext) {
            this.query = query; 
            this.expr = expression;
            this.needContext = needContext; 
        } 

        internal Query QueryTree { 
            get {
                if (needContext) {
                    throw XPathException.Create(Res.Xp_NoContext);
                } 
                return query;
            } 
        } 

        public override string Expression { 
            get { return expr; }
        }

        public virtual void CheckErrors() { 
            Debug.Assert(query != null, "In case of error in XPath we create ErrorXPathExpression");
        } 
 
        public override void AddSort(object expr, IComparer comparer) {
            // sort makes sense only when we are dealing with a query that 
            // returns a nodeset.
 	        Query evalExpr;
            if (expr is string) {
                evalExpr = new QueryBuilder().Build((string)expr, out needContext); // this will throw if expr is invalid 
            } else if (expr is CompiledXpathExpr) {
                evalExpr = ((CompiledXpathExpr)expr).QueryTree; 
	        } else { 
                throw XPathException.Create(Res.Xp_BadQueryObject);
            } 
            SortQuery sortQuery = query as SortQuery;
            if (sortQuery == null) {
                query = sortQuery = new SortQuery(query);
            } 
            sortQuery.AddSort(evalExpr, comparer);
        } 
 
        public override void AddSort(object expr, XmlSortOrder order, XmlCaseOrder caseOrder, string lang, XmlDataType dataType) {
            AddSort(expr, new XPathComparerHelper(order, caseOrder, lang, dataType)); 
        }

        public override XPathExpression Clone() {
            return new CompiledXpathExpr(Query.Clone(query), expr, needContext); 
        }
 
        public override void SetContext(XmlNamespaceManager nsManager) { 
            SetContext((IXmlNamespaceResolver)nsManager);
        } 

        public override void SetContext(IXmlNamespaceResolver nsResolver) {
            XsltContext xsltContext = nsResolver as XsltContext;
            if(xsltContext == null) { 
                if(nsResolver == null) {
                    nsResolver = new XmlNamespaceManager(new NameTable()); 
                } 
                xsltContext = new UndefinedXsltContext(nsResolver);
            } 
            query.SetXsltContext(xsltContext);

            needContext = false;
        } 

        public override XPathResultType ReturnType { get { return query.StaticType; } } 
 
        private class UndefinedXsltContext : XsltContext {
            private IXmlNamespaceResolver nsResolver; 

            public UndefinedXsltContext(IXmlNamespaceResolver nsResolver) : base(/*dummy*/false) {
                this.nsResolver = nsResolver;
            } 
            //----- Namespace support -----
            public override string DefaultNamespace { 
                get { return string.Empty; } 
            }
            public override string LookupNamespace(string prefix) { 
                Debug.Assert(prefix != null);
                if (prefix.Length == 0) {
                    return string.Empty;
                } 
                string ns = this.nsResolver.LookupNamespace(prefix);
                if (ns == null) { 
                    throw XPathException.Create(Res.XmlUndefinedAlias, prefix); 
                }
                return ns; 
            }
            //----- XsltContext support -----
            public override IXsltContextVariable ResolveVariable(string prefix, string name) {
                throw XPathException.Create(Res.Xp_UndefinedXsltContext); 
            }
            public override IXsltContextFunction ResolveFunction(string prefix, string name, XPathResultType[] ArgTypes) { 
                throw XPathException.Create(Res.Xp_UndefinedXsltContext); 
            }
            public override bool Whitespace { get{ return false; } } 
            public override bool PreserveWhitespace(XPathNavigator node) { return false; }
            public override int CompareDocument (string baseUri, string nextbaseUri) {
                return string.CompareOrdinal(baseUri, nextbaseUri);
            } 
        }
    } 
 
    internal sealed class XPathComparerHelper : IComparer {
        private XmlSortOrder order; 
        private XmlCaseOrder caseOrder;
        private CultureInfo  cinfo;
        private XmlDataType  dataType;
 
        public XPathComparerHelper(XmlSortOrder order, XmlCaseOrder caseOrder, string lang, XmlDataType dataType) {
            if (lang == null) { 
                this.cinfo = System.Threading.Thread.CurrentThread.CurrentCulture; 
            } else {
                try { 
                    this.cinfo = new CultureInfo(lang);
                }
                catch (System.ArgumentException) {
                    throw;  // Throwing an XsltException would be a breaking change 
				}
            } 
 
            if (order == XmlSortOrder.Descending) {
                if (caseOrder == XmlCaseOrder.LowerFirst) { 
                    caseOrder = XmlCaseOrder.UpperFirst;
                }
                else if (caseOrder == XmlCaseOrder.UpperFirst) {
                    caseOrder = XmlCaseOrder.LowerFirst; 
                }
            } 
 
            this.order     = order;
            this.caseOrder = caseOrder; 
            this.dataType  = dataType;
        }

        public int Compare(object x, object y) { 
            switch (this.dataType) {
            case XmlDataType.Text: 
                string s1 = Convert.ToString(x, this.cinfo); 
                string s2 = Convert.ToString(y, this.cinfo);
                int result = string.Compare(s1, s2, /*ignoreCase:*/ this.caseOrder != XmlCaseOrder.None, this.cinfo); 

                if (result != 0 || this.caseOrder == XmlCaseOrder.None)
                    return (this.order == XmlSortOrder.Ascending) ? result : -result;
 
                // If we came this far, it means that strings s1 and s2 are
                // equal to each other when case is ignored. Now it's time to check 
                // and see if they differ in case only and take into account the user 
                // requested case order for sorting purposes.
                result = string.Compare(s1, s2, /*ignoreCase:*/ false, this.cinfo); 
                return (this.caseOrder == XmlCaseOrder.LowerFirst) ? result : -result;

            case XmlDataType.Number:
                double r1 = XmlConvert.ToXPathDouble(x); 
                double r2 = XmlConvert.ToXPathDouble(y);
                result = r1.CompareTo(r2); 
                return (this.order == XmlSortOrder.Ascending) ? result : -result; 

            default: 
                // dataType doesn't support any other value
                throw new InvalidOperationException(Res.GetString(Res.Xml_InvalidOperation));
            }
        } // Compare () 
    } // class XPathComparerHelper
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
namespace MS.Internal.Xml.XPath { 
    using System;
    using System.Xml; 
    using System.Xml.XPath;
    using System.Diagnostics;
    using System.Globalization;
    using System.Collections; 
    using System.Xml.Xsl;
 
    internal class CompiledXpathExpr : XPathExpression { 
        Query query;
        string expr; 
        bool needContext;

        internal CompiledXpathExpr(Query query, string expression, bool needContext) {
            this.query = query; 
            this.expr = expression;
            this.needContext = needContext; 
        } 

        internal Query QueryTree { 
            get {
                if (needContext) {
                    throw XPathException.Create(Res.Xp_NoContext);
                } 
                return query;
            } 
        } 

        public override string Expression { 
            get { return expr; }
        }

        public virtual void CheckErrors() { 
            Debug.Assert(query != null, "In case of error in XPath we create ErrorXPathExpression");
        } 
 
        public override void AddSort(object expr, IComparer comparer) {
            // sort makes sense only when we are dealing with a query that 
            // returns a nodeset.
 	        Query evalExpr;
            if (expr is string) {
                evalExpr = new QueryBuilder().Build((string)expr, out needContext); // this will throw if expr is invalid 
            } else if (expr is CompiledXpathExpr) {
                evalExpr = ((CompiledXpathExpr)expr).QueryTree; 
	        } else { 
                throw XPathException.Create(Res.Xp_BadQueryObject);
            } 
            SortQuery sortQuery = query as SortQuery;
            if (sortQuery == null) {
                query = sortQuery = new SortQuery(query);
            } 
            sortQuery.AddSort(evalExpr, comparer);
        } 
 
        public override void AddSort(object expr, XmlSortOrder order, XmlCaseOrder caseOrder, string lang, XmlDataType dataType) {
            AddSort(expr, new XPathComparerHelper(order, caseOrder, lang, dataType)); 
        }

        public override XPathExpression Clone() {
            return new CompiledXpathExpr(Query.Clone(query), expr, needContext); 
        }
 
        public override void SetContext(XmlNamespaceManager nsManager) { 
            SetContext((IXmlNamespaceResolver)nsManager);
        } 

        public override void SetContext(IXmlNamespaceResolver nsResolver) {
            XsltContext xsltContext = nsResolver as XsltContext;
            if(xsltContext == null) { 
                if(nsResolver == null) {
                    nsResolver = new XmlNamespaceManager(new NameTable()); 
                } 
                xsltContext = new UndefinedXsltContext(nsResolver);
            } 
            query.SetXsltContext(xsltContext);

            needContext = false;
        } 

        public override XPathResultType ReturnType { get { return query.StaticType; } } 
 
        private class UndefinedXsltContext : XsltContext {
            private IXmlNamespaceResolver nsResolver; 

            public UndefinedXsltContext(IXmlNamespaceResolver nsResolver) : base(/*dummy*/false) {
                this.nsResolver = nsResolver;
            } 
            //----- Namespace support -----
            public override string DefaultNamespace { 
                get { return string.Empty; } 
            }
            public override string LookupNamespace(string prefix) { 
                Debug.Assert(prefix != null);
                if (prefix.Length == 0) {
                    return string.Empty;
                } 
                string ns = this.nsResolver.LookupNamespace(prefix);
                if (ns == null) { 
                    throw XPathException.Create(Res.XmlUndefinedAlias, prefix); 
                }
                return ns; 
            }
            //----- XsltContext support -----
            public override IXsltContextVariable ResolveVariable(string prefix, string name) {
                throw XPathException.Create(Res.Xp_UndefinedXsltContext); 
            }
            public override IXsltContextFunction ResolveFunction(string prefix, string name, XPathResultType[] ArgTypes) { 
                throw XPathException.Create(Res.Xp_UndefinedXsltContext); 
            }
            public override bool Whitespace { get{ return false; } } 
            public override bool PreserveWhitespace(XPathNavigator node) { return false; }
            public override int CompareDocument (string baseUri, string nextbaseUri) {
                return string.CompareOrdinal(baseUri, nextbaseUri);
            } 
        }
    } 
 
    internal sealed class XPathComparerHelper : IComparer {
        private XmlSortOrder order; 
        private XmlCaseOrder caseOrder;
        private CultureInfo  cinfo;
        private XmlDataType  dataType;
 
        public XPathComparerHelper(XmlSortOrder order, XmlCaseOrder caseOrder, string lang, XmlDataType dataType) {
            if (lang == null) { 
                this.cinfo = System.Threading.Thread.CurrentThread.CurrentCulture; 
            } else {
                try { 
                    this.cinfo = new CultureInfo(lang);
                }
                catch (System.ArgumentException) {
                    throw;  // Throwing an XsltException would be a breaking change 
				}
            } 
 
            if (order == XmlSortOrder.Descending) {
                if (caseOrder == XmlCaseOrder.LowerFirst) { 
                    caseOrder = XmlCaseOrder.UpperFirst;
                }
                else if (caseOrder == XmlCaseOrder.UpperFirst) {
                    caseOrder = XmlCaseOrder.LowerFirst; 
                }
            } 
 
            this.order     = order;
            this.caseOrder = caseOrder; 
            this.dataType  = dataType;
        }

        public int Compare(object x, object y) { 
            switch (this.dataType) {
            case XmlDataType.Text: 
                string s1 = Convert.ToString(x, this.cinfo); 
                string s2 = Convert.ToString(y, this.cinfo);
                int result = string.Compare(s1, s2, /*ignoreCase:*/ this.caseOrder != XmlCaseOrder.None, this.cinfo); 

                if (result != 0 || this.caseOrder == XmlCaseOrder.None)
                    return (this.order == XmlSortOrder.Ascending) ? result : -result;
 
                // If we came this far, it means that strings s1 and s2 are
                // equal to each other when case is ignored. Now it's time to check 
                // and see if they differ in case only and take into account the user 
                // requested case order for sorting purposes.
                result = string.Compare(s1, s2, /*ignoreCase:*/ false, this.cinfo); 
                return (this.caseOrder == XmlCaseOrder.LowerFirst) ? result : -result;

            case XmlDataType.Number:
                double r1 = XmlConvert.ToXPathDouble(x); 
                double r2 = XmlConvert.ToXPathDouble(y);
                result = r1.CompareTo(r2); 
                return (this.order == XmlSortOrder.Ascending) ? result : -result; 

            default: 
                // dataType doesn't support any other value
                throw new InvalidOperationException(Res.GetString(Res.Xml_InvalidOperation));
            }
        } // Compare () 
    } // class XPathComparerHelper
} 

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