XNodeNavigator.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 / Orcas / SP / ndp / fx / src / XLinq / System / Xml / Linq / XNodeNavigator.cs / 1 / XNodeNavigator.cs

                            using System; 
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Xml; 
using System.Xml.Linq;
 
namespace System.Xml.XPath 
{
    internal class XNodeNavigator : XPathNavigator, IXmlLineInfo 
    {
        const int DocumentContentMask =
            (1 << (int)XmlNodeType.Element) |
            (1 << (int)XmlNodeType.ProcessingInstruction) | 
            (1 << (int)XmlNodeType.Comment);
        static readonly int[] ElementContentMasks = { 
            0,                                              // Root 
            (1 << (int)XmlNodeType.Element),                // Element
            0,                                              // Attribute 
            0,                                              // Namespace
            (1 << (int)XmlNodeType.CDATA) |
            (1 << (int)XmlNodeType.Text),                   // Text
            0,                                              // SignificantWhitespace 
            0,                                              // Whitespace
            (1 << (int)XmlNodeType.ProcessingInstruction),  // ProcessingInstruction 
            (1 << (int)XmlNodeType.Comment),                // Comment 
            (1 << (int)XmlNodeType.Element) |
            (1 << (int)XmlNodeType.CDATA) | 
            (1 << (int)XmlNodeType.Text) |
            (1 << (int)XmlNodeType.ProcessingInstruction) |
            (1 << (int)XmlNodeType.Comment)                 // All
        }; 
        const int TextMask =
            (1 << (int)XmlNodeType.CDATA) | 
            (1 << (int)XmlNodeType.Text); 

        static XAttribute XmlNamespaceDeclaration; 

        // The navigator position is encoded by the tuple (source, parent).
        // Lazy text uses (instance, parent element). Namespace declaration uses
        // (instance, parent element). Common XObjects uses (instance, null). 
        object source;
        XElement parent; 
 
        XmlNameTable nameTable;
 
        public XNodeNavigator(XNode node, XmlNameTable nameTable) {
            this.source = node;
            this.nameTable = nameTable != null ? nameTable : CreateNameTable();
        } 

        public XNodeNavigator(XNodeNavigator other) { 
            source = other.source; 
            parent = other.parent;
            nameTable = other.nameTable; 
        }

        public override string BaseURI {
            get { 
                XObject o = source as XObject;
                if (o != null) { 
                    return o.BaseUri; 
                }
                if (parent != null) { 
                    return parent.BaseUri;
                }
                return string.Empty;
            } 
        }
 
        public override bool HasAttributes { 
            get {
                XElement e = source as XElement; 
                if (e != null) {
                    XAttribute a = e.lastAttr;
                    if (a != null) {
                        do { 
                            a = a.next;
                            if (!a.IsNamespaceDeclaration) { 
                                return true; 
                            }
                        } while (a != e.lastAttr); 
                    }
                }
                return false;
            } 
        }
 
        public override bool HasChildren { 
            get {
                XContainer c = source as XContainer; 
                if (c != null && c.content != null) {
                    XNode n = c.content as XNode;
                    if (n != null) {
                        do { 
                            n = n.next;
                            if (IsContent(c, n)) { 
                                return true; 
                            }
                        } while (n != c.content); 
                        return false;
                    }
                    string s = (string)c.content;
                    if (s.Length != 0 && (c.parent != null || c is XElement)) { 
                        return true;
                    } 
                } 
                return false;
            } 
        }

        public override bool IsEmptyElement {
            get { 
                XElement e = source as XElement;
                return e != null && e.IsEmpty; 
            } 
        }
 
        public override string LocalName {
            get { return nameTable.Add(GetLocalName()); }
        }
 
        string GetLocalName() {
            XElement e = source as XElement; 
            if (e != null) { 
                return e.Name.LocalName;
            } 
            XAttribute a = source as XAttribute;
            if (a != null) {
                if (parent != null && a.Name.NamespaceName.Length == 0) {
                    return string.Empty; // backcompat 
                }
                return a.Name.LocalName; 
            } 
            XProcessingInstruction p = source as XProcessingInstruction;
            if (p != null) { 
                return p.Target;
            }
            return string.Empty;
        } 

        public override string Name { 
            get { 
                string prefix = GetPrefix();
                if (prefix.Length == 0) { 
                    return nameTable.Add(GetLocalName());
                }
                return nameTable.Add(string.Concat(prefix, ":", GetLocalName()));
            } 
        }
 
        public override string NamespaceURI { 
            get { return nameTable.Add(GetNamespaceURI()); }
        } 

        string GetNamespaceURI() {
            XElement e = source as XElement;
            if (e != null) { 
                return e.Name.NamespaceName;
            } 
            XAttribute a = source as XAttribute; 
            if (a != null) {
                if (parent != null) { 
                    return string.Empty; // backcompat
                }
                return a.Name.NamespaceName;
            } 
            return string.Empty;
        } 
 
        public override XmlNameTable NameTable {
            get { return nameTable; } 
        }

        public override XPathNodeType NodeType {
            get { 
                XObject o = source as XObject;
                if (o != null) { 
                    switch (o.NodeType) { 
                        case XmlNodeType.Element:
                            return XPathNodeType.Element; 
                        case XmlNodeType.Attribute:
                            if (parent != null) {
                                return XPathNodeType.Namespace;
                            } 
                            return XPathNodeType.Attribute;
                        case XmlNodeType.Document: 
                            return XPathNodeType.Root; 
                        case XmlNodeType.Comment:
                            return XPathNodeType.Comment; 
                        case XmlNodeType.ProcessingInstruction:
                            return XPathNodeType.ProcessingInstruction;
                        default:
                            return XPathNodeType.Text; 
                    }
                } 
                return XPathNodeType.Text; 
            }
        } 

        public override string Prefix {
            get { return nameTable.Add(GetPrefix()); }
        } 

        string GetPrefix() { 
            XElement e = source as XElement; 
            if (e != null) {
                string prefix = e.GetPrefixOfNamespace(e.Name.Namespace); 
                if (prefix != null) {
                    return prefix;
                }
                return string.Empty; 
            }
            XAttribute a = source as XAttribute; 
            if (a != null) { 
                if (parent != null) {
                    return string.Empty; // backcompat 
                }
                string prefix = a.GetPrefixOfNamespace(a.Name.Namespace);
                if (prefix != null) {
                    return prefix; 
                }
            } 
            return string.Empty; 
        }
 
        public override object UnderlyingObject {
 	        get {
                if (source is string) {
                    // convert lazy text to eager text 
                    source = parent.LastNode;
                    parent = null; 
                } 
                return source;
	        } 
        }

        public override string Value {
            get { 
                XObject o = source as XObject;
                if (o != null) { 
                    switch (o.NodeType) { 
                        case XmlNodeType.Element:
                            return ((XElement)o).Value; 
                        case XmlNodeType.Attribute:
                            return ((XAttribute)o).Value;
                        case XmlNodeType.Document:
                            XElement root = ((XDocument)o).Root; 
                            return root != null ? root.Value : string.Empty;
                        case XmlNodeType.Text: 
                        case XmlNodeType.CDATA: 
                            return CollectText((XText)o);
                        case XmlNodeType.Comment: 
                            return ((XComment)o).Value;
                        case XmlNodeType.ProcessingInstruction:
                            return ((XProcessingInstruction)o).Data;
                        default: 
                            return string.Empty;
                    } 
                } 
                return (string)source;
            } 
        }

        public override bool CheckValidity(System.Xml.Schema.XmlSchemaSet schemas, System.Xml.Schema.ValidationEventHandler validationEventHandler) {
            throw new NotSupportedException(Res.GetString(Res.NotSupported_CheckValidity)); 
        }
 
        public override XPathNavigator Clone() { 
            return new XNodeNavigator(this);
        } 

        public override bool IsSamePosition(XPathNavigator navigator) {
            XNodeNavigator other = navigator as XNodeNavigator;
            if (other == null) { 
                return false;
            } 
            return IsSamePosition(this, other); 
        }
 
        public override bool MoveTo(XPathNavigator navigator) {
            XNodeNavigator other = navigator as XNodeNavigator;
            if (other != null) {
                source = other.source; 
                parent = other.parent;
                return true; 
            } 
            return false;
        } 

        public override bool MoveToAttribute(string localName, string namespaceName) {
            XElement e = source as XElement;
            if (e != null) { 
                XAttribute a = e.lastAttr;
                if (a != null) { 
                    do { 
                        a = a.next;
                        if (a.Name.LocalName == localName && 
                            a.Name.NamespaceName == namespaceName &&
                            !a.IsNamespaceDeclaration) {
                            source = a;
                            return true; 
                        }
                    } while (a != e.lastAttr); 
                } 
            }
            return false; 
        }

        public override bool MoveToChild(string localName, string namespaceName) {
            XContainer c = source as XContainer; 
            if (c != null && c.content != null) {
                XNode n = c.content as XNode; 
                if (n != null) { 
                    do {
                        n = n.next; 
                        XElement e = n as XElement;
                        if (e != null &&
                            e.Name.LocalName == localName &&
                            e.Name.NamespaceName == namespaceName) { 
                            source = e;
                            return true; 
                        } 
                    } while (n != c.content);
                } 
            }
            return false;
        }
 
        public override bool MoveToChild(XPathNodeType type) {
            XContainer c = source as XContainer; 
            if (c != null && c.content != null) { 
                XNode n = c.content as XNode;
                if (n != null) { 
                    int mask = GetElementContentMask(type);
                    if ((TextMask & mask) != 0 && c.parent == null && c is XDocument) {
                        mask &= ~TextMask;
                    } 
                    do {
                        n = n.next; 
                        if (((1 << (int)n.NodeType) & mask) != 0) { 
                            source = n;
                            return true; 
                        }
                    } while (n != c.content);
                    return false;
                } 
                string s = (string)c.content;
                if (s.Length != 0) { 
                    int mask = GetElementContentMask(type); 
                    if ((TextMask & mask) != 0 && c.parent == null && c is XDocument) {
                        return false; 
                    }
                    if (((1 << (int)XmlNodeType.Text) & mask) != 0) {
                        source = s;
                        parent = (XElement)c; 
                        return true;
                    } 
                } 
            }
            return false; 
        }

        public override bool MoveToFirstAttribute() {
            XElement e = source as XElement; 
            if (e != null) {
                XAttribute a = e.lastAttr; 
                if (a != null) { 
                    do {
                        a = a.next; 
                        if (!a.IsNamespaceDeclaration) {
                            source = a;
                            return true;
                        } 
                    } while (a != e.lastAttr);
                } 
            } 
            return false;
        } 

        public override bool MoveToFirstChild() {
            XContainer c = source as XContainer;
            if (c != null && c.content != null) { 
                XNode n = c.content as XNode;
                if (n != null) { 
                    do { 
                        n = n.next;
                        if (IsContent(c, n)) { 
                            source = n;
                            return true;
                        }
                    } while (n != c.content); 
                    return false;
                } 
                string s = (string)c.content; 
                if (s.Length != 0 && (c.parent != null || c is XElement)) {
                    source = s; 
                    parent = (XElement)c;
                    return true;
                }
            } 
            return false;
        } 
 
        public override bool MoveToFirstNamespace(XPathNamespaceScope scope) {
            XElement e = source as XElement; 
            if (e != null) {
                XAttribute a = null;
                switch (scope) {
                    case XPathNamespaceScope.Local: 
                        a = GetFirstNamespaceDeclarationLocal(e);
                        break; 
                    case XPathNamespaceScope.ExcludeXml: 
                        a = GetFirstNamespaceDeclarationGlobal(e);
                        while (a != null && a.Name.LocalName == "xml") { 
                            a = GetNextNamespaceDeclarationGlobal(a);
                        }
                        break;
                    case XPathNamespaceScope.All: 
                        a = GetFirstNamespaceDeclarationGlobal(e);
                        if (a == null) { 
                            a = GetXmlNamespaceDeclaration(); 
                        }
                        break; 
                }
                if (a != null) {
                    source = a;
                    parent = e; 
                    return true;
                } 
            } 
            return false;
        } 

        public override bool MoveToId(string id) {
            throw new NotSupportedException(Res.GetString(Res.NotSupported_MoveToId));
        } 

        public override bool MoveToNamespace(string localName) { 
            XElement e = source as XElement; 
            if (e != null) {
                if (localName == "xmlns") { 
                    return false; // backcompat
                }
                if (localName != null && localName.Length == 0) {
                    localName = "xmlns"; // backcompat 
                }
                XAttribute a = GetFirstNamespaceDeclarationGlobal(e); 
                while (a != null) { 
                    if (a.Name.LocalName == localName) {
                        source = a; 
                        parent = e;
                        return true;
                    }
                    a = GetNextNamespaceDeclarationGlobal(a); 
                }
                if (localName == "xml") { 
                    source = GetXmlNamespaceDeclaration(); 
                    parent = e;
                    return true; 
                }
            }
            return false;
        } 

        public override bool MoveToNext() { 
            XNode n = source as XNode; 
            if (n != null) {
                XContainer c = n.parent; 
                if (c != null && n != c.content) {
                    do {
                        XNode next = n.next;
                        if (IsContent(c, next) && !(n is XText && next is XText)) { 
                            source = next;
                            return true; 
                        } 
                        n = next;
                    } while (n != c.content); 
                }
            }
            return false;
        } 

        public override bool MoveToNext(string localName, string namespaceName) { 
            XNode n = source as XNode; 
            if (n != null) {
                XContainer c = n.parent; 
                if (c != null && n != c.content) {
                    do {
                        n = n.next;
                        XElement e = n as XElement; 
                        if (e != null &&
                            e.Name.LocalName == localName && 
                            e.Name.NamespaceName == namespaceName) { 
                            source = e;
                            return true; 
                        }
                    } while (n != c.content);
                }
            } 
            return false;
        } 
 
        public override bool MoveToNext(XPathNodeType type) {
            XNode n = source as XNode; 
            if (n != null) {
                XContainer c = n.parent;
                if (c != null && n != c.content) {
                    int mask = GetElementContentMask(type); 
                    if ((TextMask & mask) != 0 && c.parent == null && c is XDocument) {
                        mask &= ~TextMask; 
                    } 
                    do {
                        XNode next = n.next; 
                        if (((1 << (int)next.NodeType) & mask) != 0 && !(n is XText && next is XText)) {
                            source = next;
                            return true;
                        } 
                        n = next;
                    } while (n != c.content); 
                } 
            }
            return false; 
        }

        public override bool MoveToNextAttribute() {
            XAttribute a = source as XAttribute; 
            if (a != null && parent == null) {
                XElement e = (XElement)a.parent; 
                if (e != null) { 
                    while (a != e.lastAttr) {
                        a = a.next; 
                        if (!a.IsNamespaceDeclaration) {
                            source = a;
                            return true;
                        } 
                    }
                } 
            } 
            return false;
        } 

        public override bool MoveToNextNamespace(XPathNamespaceScope scope) {
            XAttribute a = source as XAttribute;
            if (a != null && parent != null && !IsXmlNamespaceDeclaration(a)) { 
                switch (scope) {
                    case XPathNamespaceScope.Local: 
                        if (a.parent != parent) { 
                            return false;
                        } 
                        a = GetNextNamespaceDeclarationLocal(a);
                        break;
                    case XPathNamespaceScope.ExcludeXml:
                        do { 
                            a = GetNextNamespaceDeclarationGlobal(a);
                        } while (a != null && 
                                 (a.Name.LocalName == "xml" || 
                                  HasNamespaceDeclarationInScope(a, parent)));
                        break; 
                    case XPathNamespaceScope.All:
                        do {
                            a = GetNextNamespaceDeclarationGlobal(a);
                        } while (a != null && 
                                 HasNamespaceDeclarationInScope(a, parent));
                        if (a == null && 
                            !HasNamespaceDeclarationInScope(GetXmlNamespaceDeclaration(), parent)) { 
                            a = GetXmlNamespaceDeclaration();
                        } 
                        break;
                }
                if (a != null) {
                    source = a; 
                    return true;
                } 
            } 
            return false;
        } 

        public override bool MoveToParent() {
            if (parent != null) {
                source = parent; 
                parent = null;
                return true; 
            } 
            XObject o = (XObject)source;
            if (o.parent != null) { 
                source = o.parent;
                return true;
            }
            return false; 
        }
 
        public override bool MoveToPrevious() { 
            XNode n = source as XNode;
            if (n != null) { 
                XContainer c = n.parent;
                if (c != null) {
                    XNode q = (XNode)c.content;
                    if (q.next != n) { 
                        XNode p = null;
                        do { 
                            q = q.next; 
                            if (IsContent(c, q)) {
                                p = p is XText && q is XText ? p : q; 
                            }
                        } while (q.next != n);
                        if (p != null) {
                            source = p; 
                            return true;
                        } 
                    } 
                }
            } 
            return false;
        }

        public override XmlReader ReadSubtree() { 
            XContainer c = source as XContainer;
            if (c == null) throw new InvalidOperationException(Res.GetString(Res.InvalidOperation_BadNodeType, NodeType)); 
            return new XNodeReader(c, nameTable); 
        }
 
        bool IXmlLineInfo.HasLineInfo() {
            IXmlLineInfo li = source as IXmlLineInfo;
            if (li != null) {
                return li.HasLineInfo(); 
            }
            return false; 
        } 

        int IXmlLineInfo.LineNumber { 
            get {
                IXmlLineInfo li = source as IXmlLineInfo;
                if (li != null) {
                    return li.LineNumber; 
                }
                return 0; 
            } 
        }
 
        int IXmlLineInfo.LinePosition {
            get {
                IXmlLineInfo li = source as IXmlLineInfo;
                if (li != null) { 
                    return li.LinePosition;
                } 
                return 0; 
            }
        } 

        static string CollectText(XText n) {
            string s = n.Value;
            if (n.parent != null) { 
                while (n != n.parent.content) {
                    n = n.next as XText; 
                    if (n == null) break; 
                    s += n.Value;
                } 
            }
            return s;
        }
 
        static XmlNameTable CreateNameTable() {
            XmlNameTable nameTable = new NameTable(); 
            nameTable.Add(string.Empty); 
            nameTable.Add(XNamespace.xmlnsPrefixNamespace);
            nameTable.Add(XNamespace.xmlPrefixNamespace); 
            return nameTable;
        }

        static bool IsContent(XContainer c, XNode n) { 
            if (c.parent != null || c is XElement) {
                return true; 
            } 
            return ((1 << (int)n.NodeType) & DocumentContentMask) != 0;
        } 

        static bool IsSamePosition(XNodeNavigator n1, XNodeNavigator n2) {
            if (n1.source == n2.source && n1.parent == n2.parent) {
                return true; 
            }
            // compare lazy text with eager text 
            if (n1.parent != null ^ n2.parent != null) { 
                XText t1 = n1.source as XText;
                if (t1 != null) { 
                    return (object)t1.Value == (object)n2.source && t1.parent == n2.parent;
                }
                XText t2 = n2.source as XText;
                if (t2 != null) { 
                    return (object)t2.Value == (object)n1.source && t2.parent == n1.parent;
                } 
            } 
            return false;
        } 

        static bool IsXmlNamespaceDeclaration(XAttribute a) {
            return (object)a == (object)GetXmlNamespaceDeclaration();
        } 

        static int GetElementContentMask(XPathNodeType type) { 
            return ElementContentMasks[(int)type]; 
        }
 
        static XAttribute GetFirstNamespaceDeclarationGlobal(XElement e) {
            do {
                XAttribute a = GetFirstNamespaceDeclarationLocal(e);
                if (a != null) { 
                    return a;
                } 
                e = e.parent as XElement; 
            } while (e != null);
            return null; 
        }

        static XAttribute GetFirstNamespaceDeclarationLocal(XElement e) {
            XAttribute a = e.lastAttr; 
            if (a != null) {
                do { 
                    a = a.next; 
                    if (a.IsNamespaceDeclaration) {
                        return a; 
                    }
                } while (a != e.lastAttr);
            }
            return null; 
        }
 
        static XAttribute GetNextNamespaceDeclarationGlobal(XAttribute a) { 
            XElement e = (XElement)a.parent;
            if (e == null) { 
                return null;
            }
            XAttribute next = GetNextNamespaceDeclarationLocal(a);
            if (next != null) { 
                return next;
            } 
            e = e.parent as XElement; 
            if (e == null) {
                return null; 
            }
            return GetFirstNamespaceDeclarationGlobal(e);
        }
 
        static XAttribute GetNextNamespaceDeclarationLocal(XAttribute a) {
            XElement e = (XElement)a.parent; 
            if (e == null) { 
                return null;
            } 
            while (a != e.lastAttr) {
                a = a.next;
                if (a.IsNamespaceDeclaration) {
                    return a; 
                }
            } 
            return null; 
        }
 
        static XAttribute GetXmlNamespaceDeclaration() {
            if (XmlNamespaceDeclaration == null) {
                System.Threading.Interlocked.CompareExchange(ref XmlNamespaceDeclaration, new XAttribute(XNamespace.Xmlns.GetName("xml"), XNamespace.xmlPrefixNamespace), null);
            } 
            return XmlNamespaceDeclaration;
        } 
 
        static bool HasNamespaceDeclarationInScope(XAttribute a, XElement e) {
            XName name = a.Name; 
            while (e != null && e != a.parent) {
                if (e.Attribute(name) != null) {
                    return true;
                } 
                e = e.parent as XElement;
            } 
            return false; 
        }
    } 

    struct XPathEvaluator
    {
        public object Evaluate(XNode node, string expression, IXmlNamespaceResolver resolver) where T : class { 
            XPathNavigator navigator = node.CreateNavigator();
            object result = navigator.Evaluate(expression, resolver); 
            if (result is XPathNodeIterator) { 
                return EvaluateIterator((XPathNodeIterator)result);
            } 
            if (!(result is T)) throw new InvalidOperationException(Res.GetString(Res.InvalidOperation_UnexpectedEvaluation, result.GetType()));
            return (T)result;
        }
 
        IEnumerable EvaluateIterator(XPathNodeIterator result) {
            foreach (XPathNavigator navigator in result) { 
                object r = navigator.UnderlyingObject; 
                if (!(r is T)) throw new InvalidOperationException(Res.GetString(Res.InvalidOperation_UnexpectedEvaluation, r.GetType()));
                yield return (T)r; 
                XText t = r as XText;
                if (t != null && t.parent != null) {
                    while (t != t.parent.content) {
                        t = t.next as XText; 
                        if (t == null) break;
                        yield return (T)(object)t; 
                    } 
                }
            } 
        }
    }

    ///  
    /// Extension methods
    ///  
    public static class Extensions 
    {
        ///  
        /// Creates an  for a given 
        /// 
        /// Extension point 
        /// An  
        public static XPathNavigator CreateNavigator(this XNode node) {
            return node.CreateNavigator(null); 
        } 

        ///  
        /// Creates an  for a given 
        /// 
        /// Extension point 
        /// The  to be used by 
        /// the 
        /// An  
        public static XPathNavigator CreateNavigator(this XNode node, XmlNameTable nameTable) { 
            if (node == null) throw new ArgumentNullException("node");
            if (node is XDocumentType) throw new ArgumentException(Res.GetString(Res.Argument_CreateNavigator, XmlNodeType.DocumentType)); 
            XText text = node as XText;
            if (text != null) {
                if (text.parent is XDocument) throw new ArgumentException(Res.GetString(Res.Argument_CreateNavigator, XmlNodeType.Whitespace));
                node = CalibrateText(text); 
            }
            return new XNodeNavigator(node, nameTable); 
        } 

        ///  
        /// Evaluates an XPath expression
        /// 
        /// Extension point 
        /// The XPath expression 
        /// The result of evaluating the expression which can be typed as bool, double, string or
        /// IEnumerable 
        public static object XPathEvaluate(this XNode node, string expression) { 
            return node.XPathEvaluate(expression, null);
        } 

        /// 
        /// Evaluates an XPath expression
        ///  
        /// Extension point 
        /// The XPath expression 
        /// A  for the namespace 
        /// prefixes used in the XPath expression
        /// The result of evaluating the expression which can be typed as bool, double, string or 
        /// IEnumerable
        public static object XPathEvaluate(this XNode node, string expression, IXmlNamespaceResolver resolver) {
            if (node == null) throw new ArgumentNullException("node");
            return new XPathEvaluator().Evaluate(node, expression, resolver); 
        }
 
        ///  
        /// Select an  using a XPath expression
        ///  
        /// Extension point 
        /// The XPath expression
        /// An  or null
        public static XElement XPathSelectElement(this XNode node, string expression) { 
            return node.XPathSelectElement(expression, null);
        } 
 
        /// 
        /// Select an  using a XPath expression 
        /// 
        /// Extension point 
        /// The XPath expression
        /// A  for the namespace 
        /// prefixes used in the XPath expression
        /// An  or null 
        public static XElement XPathSelectElement(this XNode node, string expression, IXmlNamespaceResolver resolver) { 
            return node.XPathSelectElements(expression, resolver).FirstOrDefault();
        } 

        /// 
        /// Select a set of  using a XPath expression
        ///  
        /// Extension point 
        /// The XPath expression 
        /// An  corresponding to the resulting set of elements 
        public static IEnumerable XPathSelectElements(this XNode node, string expression) {
            return node.XPathSelectElements(expression, null); 
        }

        /// 
        /// Select a set of  using a XPath expression 
        /// 
        /// Extension point  
        /// The XPath expression 
        /// A  for the namespace
        /// prefixes used in the XPath expression 
        /// An  corresponding to the resulting set of elements
        public static IEnumerable XPathSelectElements(this XNode node, string expression, IXmlNamespaceResolver resolver) {
            if (node == null) throw new ArgumentNullException("node");
            return (IEnumerable)new XPathEvaluator().Evaluate(node, expression, resolver); 
        }
 
        static XText CalibrateText(XText n) { 
            if (n.parent == null) {
                return n; 
            }
            XNode p = (XNode)n.parent.content;
            while (true) {
                p = p.next; 
                XText t = p as XText;
                if (t != null) { 
                    do { 
                        if (p == n) {
                            return t; 
                        }
                        p = p.next;
                    } while (p is XText);
                } 
            }
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System; 
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Xml; 
using System.Xml.Linq;
 
namespace System.Xml.XPath 
{
    internal class XNodeNavigator : XPathNavigator, IXmlLineInfo 
    {
        const int DocumentContentMask =
            (1 << (int)XmlNodeType.Element) |
            (1 << (int)XmlNodeType.ProcessingInstruction) | 
            (1 << (int)XmlNodeType.Comment);
        static readonly int[] ElementContentMasks = { 
            0,                                              // Root 
            (1 << (int)XmlNodeType.Element),                // Element
            0,                                              // Attribute 
            0,                                              // Namespace
            (1 << (int)XmlNodeType.CDATA) |
            (1 << (int)XmlNodeType.Text),                   // Text
            0,                                              // SignificantWhitespace 
            0,                                              // Whitespace
            (1 << (int)XmlNodeType.ProcessingInstruction),  // ProcessingInstruction 
            (1 << (int)XmlNodeType.Comment),                // Comment 
            (1 << (int)XmlNodeType.Element) |
            (1 << (int)XmlNodeType.CDATA) | 
            (1 << (int)XmlNodeType.Text) |
            (1 << (int)XmlNodeType.ProcessingInstruction) |
            (1 << (int)XmlNodeType.Comment)                 // All
        }; 
        const int TextMask =
            (1 << (int)XmlNodeType.CDATA) | 
            (1 << (int)XmlNodeType.Text); 

        static XAttribute XmlNamespaceDeclaration; 

        // The navigator position is encoded by the tuple (source, parent).
        // Lazy text uses (instance, parent element). Namespace declaration uses
        // (instance, parent element). Common XObjects uses (instance, null). 
        object source;
        XElement parent; 
 
        XmlNameTable nameTable;
 
        public XNodeNavigator(XNode node, XmlNameTable nameTable) {
            this.source = node;
            this.nameTable = nameTable != null ? nameTable : CreateNameTable();
        } 

        public XNodeNavigator(XNodeNavigator other) { 
            source = other.source; 
            parent = other.parent;
            nameTable = other.nameTable; 
        }

        public override string BaseURI {
            get { 
                XObject o = source as XObject;
                if (o != null) { 
                    return o.BaseUri; 
                }
                if (parent != null) { 
                    return parent.BaseUri;
                }
                return string.Empty;
            } 
        }
 
        public override bool HasAttributes { 
            get {
                XElement e = source as XElement; 
                if (e != null) {
                    XAttribute a = e.lastAttr;
                    if (a != null) {
                        do { 
                            a = a.next;
                            if (!a.IsNamespaceDeclaration) { 
                                return true; 
                            }
                        } while (a != e.lastAttr); 
                    }
                }
                return false;
            } 
        }
 
        public override bool HasChildren { 
            get {
                XContainer c = source as XContainer; 
                if (c != null && c.content != null) {
                    XNode n = c.content as XNode;
                    if (n != null) {
                        do { 
                            n = n.next;
                            if (IsContent(c, n)) { 
                                return true; 
                            }
                        } while (n != c.content); 
                        return false;
                    }
                    string s = (string)c.content;
                    if (s.Length != 0 && (c.parent != null || c is XElement)) { 
                        return true;
                    } 
                } 
                return false;
            } 
        }

        public override bool IsEmptyElement {
            get { 
                XElement e = source as XElement;
                return e != null && e.IsEmpty; 
            } 
        }
 
        public override string LocalName {
            get { return nameTable.Add(GetLocalName()); }
        }
 
        string GetLocalName() {
            XElement e = source as XElement; 
            if (e != null) { 
                return e.Name.LocalName;
            } 
            XAttribute a = source as XAttribute;
            if (a != null) {
                if (parent != null && a.Name.NamespaceName.Length == 0) {
                    return string.Empty; // backcompat 
                }
                return a.Name.LocalName; 
            } 
            XProcessingInstruction p = source as XProcessingInstruction;
            if (p != null) { 
                return p.Target;
            }
            return string.Empty;
        } 

        public override string Name { 
            get { 
                string prefix = GetPrefix();
                if (prefix.Length == 0) { 
                    return nameTable.Add(GetLocalName());
                }
                return nameTable.Add(string.Concat(prefix, ":", GetLocalName()));
            } 
        }
 
        public override string NamespaceURI { 
            get { return nameTable.Add(GetNamespaceURI()); }
        } 

        string GetNamespaceURI() {
            XElement e = source as XElement;
            if (e != null) { 
                return e.Name.NamespaceName;
            } 
            XAttribute a = source as XAttribute; 
            if (a != null) {
                if (parent != null) { 
                    return string.Empty; // backcompat
                }
                return a.Name.NamespaceName;
            } 
            return string.Empty;
        } 
 
        public override XmlNameTable NameTable {
            get { return nameTable; } 
        }

        public override XPathNodeType NodeType {
            get { 
                XObject o = source as XObject;
                if (o != null) { 
                    switch (o.NodeType) { 
                        case XmlNodeType.Element:
                            return XPathNodeType.Element; 
                        case XmlNodeType.Attribute:
                            if (parent != null) {
                                return XPathNodeType.Namespace;
                            } 
                            return XPathNodeType.Attribute;
                        case XmlNodeType.Document: 
                            return XPathNodeType.Root; 
                        case XmlNodeType.Comment:
                            return XPathNodeType.Comment; 
                        case XmlNodeType.ProcessingInstruction:
                            return XPathNodeType.ProcessingInstruction;
                        default:
                            return XPathNodeType.Text; 
                    }
                } 
                return XPathNodeType.Text; 
            }
        } 

        public override string Prefix {
            get { return nameTable.Add(GetPrefix()); }
        } 

        string GetPrefix() { 
            XElement e = source as XElement; 
            if (e != null) {
                string prefix = e.GetPrefixOfNamespace(e.Name.Namespace); 
                if (prefix != null) {
                    return prefix;
                }
                return string.Empty; 
            }
            XAttribute a = source as XAttribute; 
            if (a != null) { 
                if (parent != null) {
                    return string.Empty; // backcompat 
                }
                string prefix = a.GetPrefixOfNamespace(a.Name.Namespace);
                if (prefix != null) {
                    return prefix; 
                }
            } 
            return string.Empty; 
        }
 
        public override object UnderlyingObject {
 	        get {
                if (source is string) {
                    // convert lazy text to eager text 
                    source = parent.LastNode;
                    parent = null; 
                } 
                return source;
	        } 
        }

        public override string Value {
            get { 
                XObject o = source as XObject;
                if (o != null) { 
                    switch (o.NodeType) { 
                        case XmlNodeType.Element:
                            return ((XElement)o).Value; 
                        case XmlNodeType.Attribute:
                            return ((XAttribute)o).Value;
                        case XmlNodeType.Document:
                            XElement root = ((XDocument)o).Root; 
                            return root != null ? root.Value : string.Empty;
                        case XmlNodeType.Text: 
                        case XmlNodeType.CDATA: 
                            return CollectText((XText)o);
                        case XmlNodeType.Comment: 
                            return ((XComment)o).Value;
                        case XmlNodeType.ProcessingInstruction:
                            return ((XProcessingInstruction)o).Data;
                        default: 
                            return string.Empty;
                    } 
                } 
                return (string)source;
            } 
        }

        public override bool CheckValidity(System.Xml.Schema.XmlSchemaSet schemas, System.Xml.Schema.ValidationEventHandler validationEventHandler) {
            throw new NotSupportedException(Res.GetString(Res.NotSupported_CheckValidity)); 
        }
 
        public override XPathNavigator Clone() { 
            return new XNodeNavigator(this);
        } 

        public override bool IsSamePosition(XPathNavigator navigator) {
            XNodeNavigator other = navigator as XNodeNavigator;
            if (other == null) { 
                return false;
            } 
            return IsSamePosition(this, other); 
        }
 
        public override bool MoveTo(XPathNavigator navigator) {
            XNodeNavigator other = navigator as XNodeNavigator;
            if (other != null) {
                source = other.source; 
                parent = other.parent;
                return true; 
            } 
            return false;
        } 

        public override bool MoveToAttribute(string localName, string namespaceName) {
            XElement e = source as XElement;
            if (e != null) { 
                XAttribute a = e.lastAttr;
                if (a != null) { 
                    do { 
                        a = a.next;
                        if (a.Name.LocalName == localName && 
                            a.Name.NamespaceName == namespaceName &&
                            !a.IsNamespaceDeclaration) {
                            source = a;
                            return true; 
                        }
                    } while (a != e.lastAttr); 
                } 
            }
            return false; 
        }

        public override bool MoveToChild(string localName, string namespaceName) {
            XContainer c = source as XContainer; 
            if (c != null && c.content != null) {
                XNode n = c.content as XNode; 
                if (n != null) { 
                    do {
                        n = n.next; 
                        XElement e = n as XElement;
                        if (e != null &&
                            e.Name.LocalName == localName &&
                            e.Name.NamespaceName == namespaceName) { 
                            source = e;
                            return true; 
                        } 
                    } while (n != c.content);
                } 
            }
            return false;
        }
 
        public override bool MoveToChild(XPathNodeType type) {
            XContainer c = source as XContainer; 
            if (c != null && c.content != null) { 
                XNode n = c.content as XNode;
                if (n != null) { 
                    int mask = GetElementContentMask(type);
                    if ((TextMask & mask) != 0 && c.parent == null && c is XDocument) {
                        mask &= ~TextMask;
                    } 
                    do {
                        n = n.next; 
                        if (((1 << (int)n.NodeType) & mask) != 0) { 
                            source = n;
                            return true; 
                        }
                    } while (n != c.content);
                    return false;
                } 
                string s = (string)c.content;
                if (s.Length != 0) { 
                    int mask = GetElementContentMask(type); 
                    if ((TextMask & mask) != 0 && c.parent == null && c is XDocument) {
                        return false; 
                    }
                    if (((1 << (int)XmlNodeType.Text) & mask) != 0) {
                        source = s;
                        parent = (XElement)c; 
                        return true;
                    } 
                } 
            }
            return false; 
        }

        public override bool MoveToFirstAttribute() {
            XElement e = source as XElement; 
            if (e != null) {
                XAttribute a = e.lastAttr; 
                if (a != null) { 
                    do {
                        a = a.next; 
                        if (!a.IsNamespaceDeclaration) {
                            source = a;
                            return true;
                        } 
                    } while (a != e.lastAttr);
                } 
            } 
            return false;
        } 

        public override bool MoveToFirstChild() {
            XContainer c = source as XContainer;
            if (c != null && c.content != null) { 
                XNode n = c.content as XNode;
                if (n != null) { 
                    do { 
                        n = n.next;
                        if (IsContent(c, n)) { 
                            source = n;
                            return true;
                        }
                    } while (n != c.content); 
                    return false;
                } 
                string s = (string)c.content; 
                if (s.Length != 0 && (c.parent != null || c is XElement)) {
                    source = s; 
                    parent = (XElement)c;
                    return true;
                }
            } 
            return false;
        } 
 
        public override bool MoveToFirstNamespace(XPathNamespaceScope scope) {
            XElement e = source as XElement; 
            if (e != null) {
                XAttribute a = null;
                switch (scope) {
                    case XPathNamespaceScope.Local: 
                        a = GetFirstNamespaceDeclarationLocal(e);
                        break; 
                    case XPathNamespaceScope.ExcludeXml: 
                        a = GetFirstNamespaceDeclarationGlobal(e);
                        while (a != null && a.Name.LocalName == "xml") { 
                            a = GetNextNamespaceDeclarationGlobal(a);
                        }
                        break;
                    case XPathNamespaceScope.All: 
                        a = GetFirstNamespaceDeclarationGlobal(e);
                        if (a == null) { 
                            a = GetXmlNamespaceDeclaration(); 
                        }
                        break; 
                }
                if (a != null) {
                    source = a;
                    parent = e; 
                    return true;
                } 
            } 
            return false;
        } 

        public override bool MoveToId(string id) {
            throw new NotSupportedException(Res.GetString(Res.NotSupported_MoveToId));
        } 

        public override bool MoveToNamespace(string localName) { 
            XElement e = source as XElement; 
            if (e != null) {
                if (localName == "xmlns") { 
                    return false; // backcompat
                }
                if (localName != null && localName.Length == 0) {
                    localName = "xmlns"; // backcompat 
                }
                XAttribute a = GetFirstNamespaceDeclarationGlobal(e); 
                while (a != null) { 
                    if (a.Name.LocalName == localName) {
                        source = a; 
                        parent = e;
                        return true;
                    }
                    a = GetNextNamespaceDeclarationGlobal(a); 
                }
                if (localName == "xml") { 
                    source = GetXmlNamespaceDeclaration(); 
                    parent = e;
                    return true; 
                }
            }
            return false;
        } 

        public override bool MoveToNext() { 
            XNode n = source as XNode; 
            if (n != null) {
                XContainer c = n.parent; 
                if (c != null && n != c.content) {
                    do {
                        XNode next = n.next;
                        if (IsContent(c, next) && !(n is XText && next is XText)) { 
                            source = next;
                            return true; 
                        } 
                        n = next;
                    } while (n != c.content); 
                }
            }
            return false;
        } 

        public override bool MoveToNext(string localName, string namespaceName) { 
            XNode n = source as XNode; 
            if (n != null) {
                XContainer c = n.parent; 
                if (c != null && n != c.content) {
                    do {
                        n = n.next;
                        XElement e = n as XElement; 
                        if (e != null &&
                            e.Name.LocalName == localName && 
                            e.Name.NamespaceName == namespaceName) { 
                            source = e;
                            return true; 
                        }
                    } while (n != c.content);
                }
            } 
            return false;
        } 
 
        public override bool MoveToNext(XPathNodeType type) {
            XNode n = source as XNode; 
            if (n != null) {
                XContainer c = n.parent;
                if (c != null && n != c.content) {
                    int mask = GetElementContentMask(type); 
                    if ((TextMask & mask) != 0 && c.parent == null && c is XDocument) {
                        mask &= ~TextMask; 
                    } 
                    do {
                        XNode next = n.next; 
                        if (((1 << (int)next.NodeType) & mask) != 0 && !(n is XText && next is XText)) {
                            source = next;
                            return true;
                        } 
                        n = next;
                    } while (n != c.content); 
                } 
            }
            return false; 
        }

        public override bool MoveToNextAttribute() {
            XAttribute a = source as XAttribute; 
            if (a != null && parent == null) {
                XElement e = (XElement)a.parent; 
                if (e != null) { 
                    while (a != e.lastAttr) {
                        a = a.next; 
                        if (!a.IsNamespaceDeclaration) {
                            source = a;
                            return true;
                        } 
                    }
                } 
            } 
            return false;
        } 

        public override bool MoveToNextNamespace(XPathNamespaceScope scope) {
            XAttribute a = source as XAttribute;
            if (a != null && parent != null && !IsXmlNamespaceDeclaration(a)) { 
                switch (scope) {
                    case XPathNamespaceScope.Local: 
                        if (a.parent != parent) { 
                            return false;
                        } 
                        a = GetNextNamespaceDeclarationLocal(a);
                        break;
                    case XPathNamespaceScope.ExcludeXml:
                        do { 
                            a = GetNextNamespaceDeclarationGlobal(a);
                        } while (a != null && 
                                 (a.Name.LocalName == "xml" || 
                                  HasNamespaceDeclarationInScope(a, parent)));
                        break; 
                    case XPathNamespaceScope.All:
                        do {
                            a = GetNextNamespaceDeclarationGlobal(a);
                        } while (a != null && 
                                 HasNamespaceDeclarationInScope(a, parent));
                        if (a == null && 
                            !HasNamespaceDeclarationInScope(GetXmlNamespaceDeclaration(), parent)) { 
                            a = GetXmlNamespaceDeclaration();
                        } 
                        break;
                }
                if (a != null) {
                    source = a; 
                    return true;
                } 
            } 
            return false;
        } 

        public override bool MoveToParent() {
            if (parent != null) {
                source = parent; 
                parent = null;
                return true; 
            } 
            XObject o = (XObject)source;
            if (o.parent != null) { 
                source = o.parent;
                return true;
            }
            return false; 
        }
 
        public override bool MoveToPrevious() { 
            XNode n = source as XNode;
            if (n != null) { 
                XContainer c = n.parent;
                if (c != null) {
                    XNode q = (XNode)c.content;
                    if (q.next != n) { 
                        XNode p = null;
                        do { 
                            q = q.next; 
                            if (IsContent(c, q)) {
                                p = p is XText && q is XText ? p : q; 
                            }
                        } while (q.next != n);
                        if (p != null) {
                            source = p; 
                            return true;
                        } 
                    } 
                }
            } 
            return false;
        }

        public override XmlReader ReadSubtree() { 
            XContainer c = source as XContainer;
            if (c == null) throw new InvalidOperationException(Res.GetString(Res.InvalidOperation_BadNodeType, NodeType)); 
            return new XNodeReader(c, nameTable); 
        }
 
        bool IXmlLineInfo.HasLineInfo() {
            IXmlLineInfo li = source as IXmlLineInfo;
            if (li != null) {
                return li.HasLineInfo(); 
            }
            return false; 
        } 

        int IXmlLineInfo.LineNumber { 
            get {
                IXmlLineInfo li = source as IXmlLineInfo;
                if (li != null) {
                    return li.LineNumber; 
                }
                return 0; 
            } 
        }
 
        int IXmlLineInfo.LinePosition {
            get {
                IXmlLineInfo li = source as IXmlLineInfo;
                if (li != null) { 
                    return li.LinePosition;
                } 
                return 0; 
            }
        } 

        static string CollectText(XText n) {
            string s = n.Value;
            if (n.parent != null) { 
                while (n != n.parent.content) {
                    n = n.next as XText; 
                    if (n == null) break; 
                    s += n.Value;
                } 
            }
            return s;
        }
 
        static XmlNameTable CreateNameTable() {
            XmlNameTable nameTable = new NameTable(); 
            nameTable.Add(string.Empty); 
            nameTable.Add(XNamespace.xmlnsPrefixNamespace);
            nameTable.Add(XNamespace.xmlPrefixNamespace); 
            return nameTable;
        }

        static bool IsContent(XContainer c, XNode n) { 
            if (c.parent != null || c is XElement) {
                return true; 
            } 
            return ((1 << (int)n.NodeType) & DocumentContentMask) != 0;
        } 

        static bool IsSamePosition(XNodeNavigator n1, XNodeNavigator n2) {
            if (n1.source == n2.source && n1.parent == n2.parent) {
                return true; 
            }
            // compare lazy text with eager text 
            if (n1.parent != null ^ n2.parent != null) { 
                XText t1 = n1.source as XText;
                if (t1 != null) { 
                    return (object)t1.Value == (object)n2.source && t1.parent == n2.parent;
                }
                XText t2 = n2.source as XText;
                if (t2 != null) { 
                    return (object)t2.Value == (object)n1.source && t2.parent == n1.parent;
                } 
            } 
            return false;
        } 

        static bool IsXmlNamespaceDeclaration(XAttribute a) {
            return (object)a == (object)GetXmlNamespaceDeclaration();
        } 

        static int GetElementContentMask(XPathNodeType type) { 
            return ElementContentMasks[(int)type]; 
        }
 
        static XAttribute GetFirstNamespaceDeclarationGlobal(XElement e) {
            do {
                XAttribute a = GetFirstNamespaceDeclarationLocal(e);
                if (a != null) { 
                    return a;
                } 
                e = e.parent as XElement; 
            } while (e != null);
            return null; 
        }

        static XAttribute GetFirstNamespaceDeclarationLocal(XElement e) {
            XAttribute a = e.lastAttr; 
            if (a != null) {
                do { 
                    a = a.next; 
                    if (a.IsNamespaceDeclaration) {
                        return a; 
                    }
                } while (a != e.lastAttr);
            }
            return null; 
        }
 
        static XAttribute GetNextNamespaceDeclarationGlobal(XAttribute a) { 
            XElement e = (XElement)a.parent;
            if (e == null) { 
                return null;
            }
            XAttribute next = GetNextNamespaceDeclarationLocal(a);
            if (next != null) { 
                return next;
            } 
            e = e.parent as XElement; 
            if (e == null) {
                return null; 
            }
            return GetFirstNamespaceDeclarationGlobal(e);
        }
 
        static XAttribute GetNextNamespaceDeclarationLocal(XAttribute a) {
            XElement e = (XElement)a.parent; 
            if (e == null) { 
                return null;
            } 
            while (a != e.lastAttr) {
                a = a.next;
                if (a.IsNamespaceDeclaration) {
                    return a; 
                }
            } 
            return null; 
        }
 
        static XAttribute GetXmlNamespaceDeclaration() {
            if (XmlNamespaceDeclaration == null) {
                System.Threading.Interlocked.CompareExchange(ref XmlNamespaceDeclaration, new XAttribute(XNamespace.Xmlns.GetName("xml"), XNamespace.xmlPrefixNamespace), null);
            } 
            return XmlNamespaceDeclaration;
        } 
 
        static bool HasNamespaceDeclarationInScope(XAttribute a, XElement e) {
            XName name = a.Name; 
            while (e != null && e != a.parent) {
                if (e.Attribute(name) != null) {
                    return true;
                } 
                e = e.parent as XElement;
            } 
            return false; 
        }
    } 

    struct XPathEvaluator
    {
        public object Evaluate(XNode node, string expression, IXmlNamespaceResolver resolver) where T : class { 
            XPathNavigator navigator = node.CreateNavigator();
            object result = navigator.Evaluate(expression, resolver); 
            if (result is XPathNodeIterator) { 
                return EvaluateIterator((XPathNodeIterator)result);
            } 
            if (!(result is T)) throw new InvalidOperationException(Res.GetString(Res.InvalidOperation_UnexpectedEvaluation, result.GetType()));
            return (T)result;
        }
 
        IEnumerable EvaluateIterator(XPathNodeIterator result) {
            foreach (XPathNavigator navigator in result) { 
                object r = navigator.UnderlyingObject; 
                if (!(r is T)) throw new InvalidOperationException(Res.GetString(Res.InvalidOperation_UnexpectedEvaluation, r.GetType()));
                yield return (T)r; 
                XText t = r as XText;
                if (t != null && t.parent != null) {
                    while (t != t.parent.content) {
                        t = t.next as XText; 
                        if (t == null) break;
                        yield return (T)(object)t; 
                    } 
                }
            } 
        }
    }

    ///  
    /// Extension methods
    ///  
    public static class Extensions 
    {
        ///  
        /// Creates an  for a given 
        /// 
        /// Extension point 
        /// An  
        public static XPathNavigator CreateNavigator(this XNode node) {
            return node.CreateNavigator(null); 
        } 

        ///  
        /// Creates an  for a given 
        /// 
        /// Extension point 
        /// The  to be used by 
        /// the 
        /// An  
        public static XPathNavigator CreateNavigator(this XNode node, XmlNameTable nameTable) { 
            if (node == null) throw new ArgumentNullException("node");
            if (node is XDocumentType) throw new ArgumentException(Res.GetString(Res.Argument_CreateNavigator, XmlNodeType.DocumentType)); 
            XText text = node as XText;
            if (text != null) {
                if (text.parent is XDocument) throw new ArgumentException(Res.GetString(Res.Argument_CreateNavigator, XmlNodeType.Whitespace));
                node = CalibrateText(text); 
            }
            return new XNodeNavigator(node, nameTable); 
        } 

        ///  
        /// Evaluates an XPath expression
        /// 
        /// Extension point 
        /// The XPath expression 
        /// The result of evaluating the expression which can be typed as bool, double, string or
        /// IEnumerable 
        public static object XPathEvaluate(this XNode node, string expression) { 
            return node.XPathEvaluate(expression, null);
        } 

        /// 
        /// Evaluates an XPath expression
        ///  
        /// Extension point 
        /// The XPath expression 
        /// A  for the namespace 
        /// prefixes used in the XPath expression
        /// The result of evaluating the expression which can be typed as bool, double, string or 
        /// IEnumerable
        public static object XPathEvaluate(this XNode node, string expression, IXmlNamespaceResolver resolver) {
            if (node == null) throw new ArgumentNullException("node");
            return new XPathEvaluator().Evaluate(node, expression, resolver); 
        }
 
        ///  
        /// Select an  using a XPath expression
        ///  
        /// Extension point 
        /// The XPath expression
        /// An  or null
        public static XElement XPathSelectElement(this XNode node, string expression) { 
            return node.XPathSelectElement(expression, null);
        } 
 
        /// 
        /// Select an  using a XPath expression 
        /// 
        /// Extension point 
        /// The XPath expression
        /// A  for the namespace 
        /// prefixes used in the XPath expression
        /// An  or null 
        public static XElement XPathSelectElement(this XNode node, string expression, IXmlNamespaceResolver resolver) { 
            return node.XPathSelectElements(expression, resolver).FirstOrDefault();
        } 

        /// 
        /// Select a set of  using a XPath expression
        ///  
        /// Extension point 
        /// The XPath expression 
        /// An  corresponding to the resulting set of elements 
        public static IEnumerable XPathSelectElements(this XNode node, string expression) {
            return node.XPathSelectElements(expression, null); 
        }

        /// 
        /// Select a set of  using a XPath expression 
        /// 
        /// Extension point  
        /// The XPath expression 
        /// A  for the namespace
        /// prefixes used in the XPath expression 
        /// An  corresponding to the resulting set of elements
        public static IEnumerable XPathSelectElements(this XNode node, string expression, IXmlNamespaceResolver resolver) {
            if (node == null) throw new ArgumentNullException("node");
            return (IEnumerable)new XPathEvaluator().Evaluate(node, expression, resolver); 
        }
 
        static XText CalibrateText(XText n) { 
            if (n.parent == null) {
                return n; 
            }
            XNode p = (XNode)n.parent.content;
            while (true) {
                p = p.next; 
                XText t = p as XText;
                if (t != null) { 
                    do { 
                        if (p == n) {
                            return t; 
                        }
                        p = p.next;
                    } while (p is XText);
                } 
            }
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

                        

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