This is the default XPath/XQuery data model cache implementation. It will be used whenever the user does not supply his own XPathNavigator implementation.
Inheritance: System.Xml.XPath.XPathNavigator, IXmlLineInfo
        /// <summary>
        /// Returns:
        ///     XmlNodeOrder.Unknown -- This navigator and the "other" navigator are not of the same type, or the
        ///                             navigator's are not positioned on nodes in the same document.
        ///     XmlNodeOrder.Before -- This navigator's current node is before the "other" navigator's current node
        ///                            in document order.
        ///     XmlNodeOrder.After -- This navigator's current node is after the "other" navigator's current node
        ///                           in document order.
        ///     XmlNodeOrder.Same -- This navigator is positioned on the same node as the "other" navigator.
        /// </summary>
        public override XmlNodeOrder ComparePosition(XPathNavigator other)
        {
            XPathDocumentNavigator that = other as XPathDocumentNavigator;

            if (that != null)
            {
                XPathDocument thisDoc = _pageCurrent[_idxCurrent].Document;
                XPathDocument thatDoc = that._pageCurrent[that._idxCurrent].Document;
                if ((object)thisDoc == (object)thatDoc)
                {
                    int locThis = GetPrimaryLocation();
                    int locThat = that.GetPrimaryLocation();

                    if (locThis == locThat)
                    {
                        locThis = GetSecondaryLocation();
                        locThat = that.GetSecondaryLocation();

                        if (locThis == locThat)
                        {
                            return(XmlNodeOrder.Same);
                        }
                    }
                    return((locThis < locThat) ? XmlNodeOrder.Before : XmlNodeOrder.After);
                }
            }
            return(XmlNodeOrder.Unknown);
        }
示例#2
0
        public override bool IsDescendant(XPathNavigator other)
        {
            XPathDocumentNavigator navigator = other as XPathDocumentNavigator;

            if (navigator != null)
            {
                XPathNode[] pageParent;
                int         idxParent;
                if (navigator.idxParent != 0)
                {
                    pageParent = navigator.pageParent;
                    idxParent  = navigator.idxParent;
                }
                else
                {
                    idxParent = navigator.pageCurrent[navigator.idxCurrent].GetParent(out pageParent);
                }
                while (idxParent != 0)
                {
                    if ((idxParent == this.idxCurrent) && (pageParent == this.pageCurrent))
                    {
                        return(true);
                    }
                    idxParent = pageParent[idxParent].GetParent(out pageParent);
                }
            }
            return(false);
        }
        /// <summary>
        /// Return true if the "other" navigator's current node is a descendant of this navigator's current node.
        /// </summary>
        public override bool IsDescendant(XPathNavigator other)
        {
            XPathDocumentNavigator that = other as XPathDocumentNavigator;

            if (that != null)
            {
                XPathNode[] pageThat;
                int         idxThat;

                // If that current node's parent is virtualized, then start with the virtual parent
                if (that._idxParent != 0)
                {
                    pageThat = that._pageParent;
                    idxThat  = that._idxParent;
                }
                else
                {
                    idxThat = that._pageCurrent[that._idxCurrent].GetParent(out pageThat);
                }

                while (idxThat != 0)
                {
                    if (idxThat == _idxCurrent && pageThat == _pageCurrent)
                    {
                        return(true);
                    }
                    idxThat = pageThat[idxThat].GetParent(out pageThat);
                }
            }
            return(false);
        }
示例#4
0
        public override XmlNodeOrder ComparePosition(XPathNavigator other)
        {
            XPathDocumentNavigator navigator = other as XPathDocumentNavigator;

            if (navigator != null)
            {
                XPathDocument document  = this.pageCurrent[this.idxCurrent].Document;
                XPathDocument document2 = navigator.pageCurrent[navigator.idxCurrent].Document;
                if (document == document2)
                {
                    int primaryLocation   = this.GetPrimaryLocation();
                    int secondaryLocation = navigator.GetPrimaryLocation();
                    if (primaryLocation == secondaryLocation)
                    {
                        primaryLocation   = this.GetSecondaryLocation();
                        secondaryLocation = navigator.GetSecondaryLocation();
                        if (primaryLocation == secondaryLocation)
                        {
                            return(XmlNodeOrder.Same);
                        }
                    }
                    if (primaryLocation >= secondaryLocation)
                    {
                        return(XmlNodeOrder.After);
                    }
                    return(XmlNodeOrder.Before);
                }
            }
            return(XmlNodeOrder.Unknown);
        }
 /// <summary>
 /// Create a new iterator that is a copy of "iter".
 /// </summary>
 public XPathDocumentElementDescendantIterator(XPathDocumentElementDescendantIterator iter) : base(iter)
 {
     this.end          = iter.end;
     this.localName    = iter.localName;
     this.namespaceUri = iter.namespaceUri;
     this.matchSelf    = iter.matchSelf;
 }
        /// <summary>
        /// Create an iterator that ranges over all element children of "parent" having the specified QName.
        /// </summary>
        public XPathDocumentElementChildIterator(XPathDocumentNavigator parent, string name, string namespaceURI) : base(parent)
        {
            ArgumentNullException.ThrowIfNull(namespaceURI);

            _localName    = parent.NameTable.Get(name);
            _namespaceUri = namespaceURI;
        }
示例#7
0
 /// <summary>
 /// Create a new iterator that is a copy of "iter".
 /// </summary>
 public XPathDocumentElementDescendantIterator(XPathDocumentElementDescendantIterator iter) : base(iter)
 {
     _end          = iter._end;
     _localName    = iter._localName;
     _namespaceUri = iter._namespaceUri;
     _matchSelf    = iter._matchSelf;
 }
示例#8
0
 public XPathDocumentElementChildIterator(XPathDocumentNavigator parent, string name, string namespaceURI) : base(parent)
 {
     if (namespaceURI == null)
     {
         throw new ArgumentNullException("namespaceURI");
     }
     this.localName    = parent.NameTable.Get(name);
     this.namespaceUri = namespaceURI;
 }
示例#9
0
        public override bool IsSamePosition(XPathNavigator other)
        {
            XPathDocumentNavigator navigator = other as XPathDocumentNavigator;

            if (navigator == null)
            {
                return(false);
            }
            return((((this.idxCurrent == navigator.idxCurrent) && (this.pageCurrent == navigator.pageCurrent)) && (this.idxParent == navigator.idxParent)) && (this.pageParent == navigator.pageParent));
        }
 public XPathDocumentKindDescendantIterator(XPathDocumentNavigator root, XPathNodeType typ, bool matchSelf) : base(root)
 {
     this.typ       = typ;
     this.matchSelf = matchSelf;
     if (root.NodeType != XPathNodeType.Root)
     {
         this.end = new XPathDocumentNavigator(root);
         this.end.MoveToNonDescendant();
     }
 }
示例#11
0
 /// <summary>
 /// Returns true if this navigator is positioned to the same node as the "other" navigator.  Returns false
 /// if not, or if the "other" navigator is not the same type as this navigator.
 /// </summary>
 public override bool IsSamePosition(XPathNavigator other)
 {
     XPathDocumentNavigator that = other as XPathDocumentNavigator;
     if (that != null)
     {
         return _idxCurrent == that._idxCurrent && _pageCurrent == that._pageCurrent &&
                _idxParent == that._idxParent && _pageParent == that._pageParent;
     }
     return false;
 }
示例#12
0
        /// <summary>
        /// Returns true if this navigator is positioned to the same node as the "other" navigator.  Returns false
        /// if not, or if the "other" navigator is not the same type as this navigator.
        /// </summary>
        public override bool IsSamePosition(XPathNavigator other)
        {
            XPathDocumentNavigator that = other as XPathDocumentNavigator;

            if (that != null)
            {
                return(this.idxCurrent == that.idxCurrent && this.pageCurrent == that.pageCurrent &&
                       this.idxParent == that.idxParent && this.pageParent == that.pageParent);
            }
            return(false);
        }
示例#13
0
        /// <summary>
        /// Create an iterator that ranges over all content descendants of "root" having the specified XPathNodeType.
        /// </summary>
        public XPathDocumentKindDescendantIterator(XPathDocumentNavigator root, XPathNodeType typ, bool matchSelf) : base(root)
        {
            this.typ       = typ;
            this.matchSelf = matchSelf;

            // Find the next non-descendant node that follows "root" in document order
            if (root.NodeType != XPathNodeType.Root)
            {
                this.end = new XPathDocumentNavigator(root);
                this.end.MoveToNonDescendant();
            }
        }
示例#14
0
 /// <summary>
 /// Position this navigator to the same position as the "other" navigator.  If the "other" navigator
 /// is not of the same type as this navigator, then return false.
 /// </summary>
 public override bool MoveTo(XPathNavigator other)
 {
     XPathDocumentNavigator that = other as XPathDocumentNavigator;
     if (that != null)
     {
         _pageCurrent = that._pageCurrent;
         _idxCurrent = that._idxCurrent;
         _pageParent = that._pageParent;
         _idxParent = that._idxParent;
         return true;
     }
     return false;
 }
示例#15
0
        /// <summary>
        /// Position this navigator to the same position as the "other" navigator.  If the "other" navigator
        /// is not of the same type as this navigator, then return false.
        /// </summary>
        public override bool MoveTo(XPathNavigator other)
        {
            XPathDocumentNavigator that = other as XPathDocumentNavigator;

            if (that != null)
            {
                this.pageCurrent = that.pageCurrent;
                this.idxCurrent  = that.idxCurrent;
                this.pageParent  = that.pageParent;
                this.idxParent   = that.idxParent;
                return(true);
            }
            return(false);
        }
        /// <summary>
        /// Create an iterator that ranges over all element descendants of "root" having the specified QName.
        /// </summary>
        public XPathDocumentElementDescendantIterator(XPathDocumentNavigator root, string name, string namespaceURI, bool matchSelf) : base(root)
        {
            ArgumentNullException.ThrowIfNull(namespaceURI);

            _localName    = root.NameTable.Get(name);
            _namespaceUri = namespaceURI;
            _matchSelf    = matchSelf;

            // Find the next non-descendant node that follows "root" in document order
            if (root.NodeType != XPathNodeType.Root)
            {
                _end = new XPathDocumentNavigator(root);
                _end.MoveToNonDescendant();
            }
        }
示例#17
0
 public XPathDocumentElementDescendantIterator(XPathDocumentNavigator root, string name, string namespaceURI, bool matchSelf) : base(root)
 {
     if (namespaceURI == null)
     {
         throw new ArgumentNullException("namespaceURI");
     }
     this.localName    = root.NameTable.Get(name);
     this.namespaceUri = namespaceURI;
     this.matchSelf    = matchSelf;
     if (root.NodeType != XPathNodeType.Root)
     {
         this.end = new XPathDocumentNavigator(root);
         this.end.MoveToNonDescendant();
     }
 }
示例#18
0
 private int GetFollowingEnd(XPathDocumentNavigator end, bool useParentOfVirtual, out XPathNode[] pageEnd)
 {
     if ((end != null) && (this.pageCurrent[this.idxCurrent].Document == end.pageCurrent[end.idxCurrent].Document))
     {
         if (end.idxParent == 0)
         {
             pageEnd = end.pageCurrent;
             return(end.idxCurrent);
         }
         pageEnd = end.pageParent;
         if (!useParentOfVirtual)
         {
             return(end.idxParent + 1);
         }
         return(end.idxParent);
     }
     pageEnd = null;
     return(0);
 }
示例#19
0
        /// <summary>
        /// "end" is positioned on a node which terminates a following scan.  Return the page and index of "end" if it
        /// is positioned to a non-virtual node.  If "end" is positioned to a virtual node:
        ///    1. If useParentOfVirtual is true, then return the page and index of the virtual node's parent
        ///    2. If useParentOfVirtual is false, then return the page and index of the virtual node's parent + 1.
        /// </summary>
        private int GetFollowingEnd(XPathDocumentNavigator end, bool useParentOfVirtual, out XPathNode[] pageEnd)
        {
            // If ending navigator is positioned to a node in another document, then return null
            if (end != null && _pageCurrent[_idxCurrent].Document == end._pageCurrent[end._idxCurrent].Document)
            {
                // If the ending navigator is not positioned on a virtual node, then return its current node
                if (end._idxParent == 0)
                {
                    pageEnd = end._pageCurrent;
                    return(end._idxCurrent);
                }

                // If the ending navigator is positioned on an attribute, namespace, or virtual text node, then use the
                // next physical node instead, as the results will be the same.
                pageEnd = end._pageParent;
                return((useParentOfVirtual) ? end._idxParent : end._idxParent + 1);
            }

            // No following, so set pageEnd to null and return an index of 0
            pageEnd = null;
            return(0);
        }
 /// <summary>
 /// Create an iterator that ranges over all element children of "parent" having the specified QName.
 /// </summary>
 public XPathDocumentElementChildIterator(XPathDocumentNavigator parent, string name, string namespaceURI !!) : base(parent)
 /// <summary>
 /// Create a new iterator that is a copy of "iter".
 /// </summary>
 protected XPathDocumentBaseIterator(XPathDocumentBaseIterator iter)
 {
     this.ctxt = new XPathDocumentNavigator(iter.ctxt);
     this.pos  = iter.pos;
 }
 /// <summary>
 /// Create a new iterator that is initially positioned on the "ctxt" node.
 /// </summary>
 protected XPathDocumentBaseIterator(XPathDocumentNavigator ctxt)
 {
     this.ctxt = new XPathDocumentNavigator(ctxt);
 }
示例#23
0
 /// <summary>
 /// Create a new iterator that is a copy of "iter".
 /// </summary>
 public XPathDocumentKindDescendantIterator(XPathDocumentKindDescendantIterator iter) : base(iter)
 {
     this.end       = iter.end;
     this.typ       = iter.typ;
     this.matchSelf = iter.matchSelf;
 }
示例#24
0
 /// <summary>
 /// Create a new iterator that is a copy of "iter".
 /// </summary>
 public XPathDocumentKindDescendantIterator(XPathDocumentKindDescendantIterator iter) : base(iter)
 {
     _end       = iter._end;
     _typ       = iter._typ;
     _matchSelf = iter._matchSelf;
 }
示例#25
0
        public override bool MoveToFollowing(XPathNodeType type, XPathNavigator end)
        {
            XPathNode[]            nodeArray2;
            int                    num2;
            XPathDocumentNavigator navigator = end as XPathDocumentNavigator;

            if ((type == XPathNodeType.Text) || (type == XPathNodeType.All))
            {
                if (this.pageCurrent[this.idxCurrent].HasCollapsedText)
                {
                    if (((navigator != null) && (this.idxCurrent == navigator.idxParent)) && (this.pageCurrent == navigator.pageParent))
                    {
                        return(false);
                    }
                    this.pageParent = this.pageCurrent;
                    this.idxParent  = this.idxCurrent;
                    this.idxCurrent = this.pageCurrent[this.idxCurrent].Document.GetCollapsedTextNode(out this.pageCurrent);
                    return(true);
                }
                if (type == XPathNodeType.Text)
                {
                    XPathNode[] pageParent;
                    int         idxParent;
                    num2 = this.GetFollowingEnd(navigator, true, out nodeArray2);
                    if (this.idxParent != 0)
                    {
                        pageParent = this.pageParent;
                        idxParent  = this.idxParent;
                    }
                    else
                    {
                        pageParent = this.pageCurrent;
                        idxParent  = this.idxCurrent;
                    }
                    if (((navigator != null) && (navigator.idxParent != 0)) && ((idxParent == num2) && (pageParent == nodeArray2)))
                    {
                        return(false);
                    }
                    if (!XPathNodeHelper.GetTextFollowing(ref pageParent, ref idxParent, nodeArray2, num2))
                    {
                        return(false);
                    }
                    if (pageParent[idxParent].NodeType == XPathNodeType.Element)
                    {
                        this.idxCurrent = pageParent[idxParent].Document.GetCollapsedTextNode(out this.pageCurrent);
                        this.pageParent = pageParent;
                        this.idxParent  = idxParent;
                    }
                    else
                    {
                        this.pageCurrent = pageParent;
                        this.idxCurrent  = idxParent;
                        this.pageParent  = null;
                        this.idxParent   = 0;
                    }
                    return(true);
                }
            }
            num2 = this.GetFollowingEnd(navigator, false, out nodeArray2);
            if (this.idxParent == 0)
            {
                return(XPathNodeHelper.GetContentFollowing(ref this.pageCurrent, ref this.idxCurrent, nodeArray2, num2, type));
            }
            if (!XPathNodeHelper.GetContentFollowing(ref this.pageParent, ref this.idxParent, nodeArray2, num2, type))
            {
                return(false);
            }
            this.pageCurrent = this.pageParent;
            this.idxCurrent  = this.idxParent;
            this.pageParent  = null;
            this.idxParent   = 0;
            return(true);
        }
示例#26
0
 /// <summary>
 /// Create an iterator that ranges over all content children of "parent" having the specified XPathNodeType.
 /// </summary>
 public XPathDocumentKindChildIterator(XPathDocumentNavigator parent, XPathNodeType typ) : base(parent)
 {
     this.typ = typ;
 }
示例#27
0
 public XPathDocumentNavigator(XPathDocumentNavigator nav) : this(nav._pageCurrent, nav._idxCurrent, nav._pageParent, nav._idxParent)
 {
     _atomizedLocalName = nav._atomizedLocalName;
 }
        /// <summary>
        /// Move to the next node that:
        ///   1. Follows the current node in document order (includes descendants, unlike XPath following axis)
        ///   2. Precedes "end" in document order (if end is null, then all following nodes in the document are considered)
        ///   3. Has the specified XPathNodeType
        /// Return false if the current node has no matching following nodes.
        /// </summary>
        public override bool MoveToFollowing(XPathNodeType type, XPathNavigator end)
        {
            XPathDocumentNavigator endTiny = end as XPathDocumentNavigator;

            XPathNode[] page, pageEnd;
            int         idx, idxEnd;

            // If searching for text, make sure to handle collapsed text nodes correctly
            if (type == XPathNodeType.Text || type == XPathNodeType.All)
            {
                if (_pageCurrent[_idxCurrent].HasCollapsedText)
                {
                    // Positioned on an element with collapsed text, so return the virtual text node, assuming it's before "end"
                    if (endTiny != null && _idxCurrent == endTiny._idxParent && _pageCurrent == endTiny._pageParent)
                    {
                        // "end" is positioned to a virtual attribute, namespace, or text node
                        return(false);
                    }

                    _pageParent = _pageCurrent;
                    _idxParent  = _idxCurrent;
                    _idxCurrent = _pageCurrent[_idxCurrent].Document.GetCollapsedTextNode(out _pageCurrent);
                    return(true);
                }

                if (type == XPathNodeType.Text)
                {
                    // Get node on which scan ends (null if rest of document should be scanned, parent if positioned on virtual node)
                    idxEnd = GetFollowingEnd(endTiny, true, out pageEnd);

                    // If this navigator is positioned on a virtual node, then compute following of parent
                    if (_idxParent != 0)
                    {
                        page = _pageParent;
                        idx  = _idxParent;
                    }
                    else
                    {
                        page = _pageCurrent;
                        idx  = _idxCurrent;
                    }

                    // If ending node is a virtual node, and current node is its parent, then we're done
                    if (endTiny != null && endTiny._idxParent != 0 && idx == idxEnd && page == pageEnd)
                    {
                        return(false);
                    }

                    // Get all virtual (collapsed) and physical text nodes which follow the current node
                    if (!XPathNodeHelper.GetTextFollowing(ref page, ref idx, pageEnd, idxEnd))
                    {
                        return(false);
                    }

                    if (page[idx].NodeType == XPathNodeType.Element)
                    {
                        // Virtualize collapsed text nodes
                        Debug.Assert(page[idx].HasCollapsedText);
                        _idxCurrent = page[idx].Document.GetCollapsedTextNode(out _pageCurrent);
                        _pageParent = page;
                        _idxParent  = idx;
                    }
                    else
                    {
                        // Physical text node
                        Debug.Assert(page[idx].IsText);
                        _pageCurrent = page;
                        _idxCurrent  = idx;
                        _pageParent  = null;
                        _idxParent   = 0;
                    }
                    return(true);
                }
            }

            // Get node on which scan ends (null if rest of document should be scanned, parent + 1 if positioned on virtual node)
            idxEnd = GetFollowingEnd(endTiny, false, out pageEnd);

            // If this navigator is positioned on a virtual node, then compute following of parent
            if (_idxParent != 0)
            {
                if (!XPathNodeHelper.GetContentFollowing(ref _pageParent, ref _idxParent, pageEnd, idxEnd, type))
                {
                    return(false);
                }

                _pageCurrent = _pageParent;
                _idxCurrent  = _idxParent;
                _pageParent  = null;
                _idxParent   = 0;
                return(true);
            }

            return(XPathNodeHelper.GetContentFollowing(ref _pageCurrent, ref _idxCurrent, pageEnd, idxEnd, type));
        }