IsDescendant() 공개 메소드

public IsDescendant ( XPathNavigator nav ) : bool
nav XPathNavigator
리턴 bool
		public virtual XmlNodeOrder ComparePosition (XPathNavigator nav)
		{
			if (IsSamePosition (nav))
				return XmlNodeOrder.Same;

			// quick check for direct descendant
			if (IsDescendant (nav))
				return XmlNodeOrder.Before;

			// quick check for direct ancestor
			if (nav.IsDescendant (this))
				return XmlNodeOrder.After;

			XPathNavigator nav1 = Clone ();
			XPathNavigator nav2 = nav.Clone ();

			// check if document instance is the same.
			nav1.MoveToRoot ();
			nav2.MoveToRoot ();
			if (!nav1.IsSamePosition (nav2))
				return XmlNodeOrder.Unknown;
			nav1.MoveTo (this);
			nav2.MoveTo (nav);

			int depth1 = 0;
			while (nav1.MoveToParent ())
				depth1++;
			nav1.MoveTo (this);
			int depth2 = 0;
			while (nav2.MoveToParent ())
				depth2++;
			nav2.MoveTo (nav);

			// find common parent depth
			int common = depth1;
			for (;common > depth2; common--)
				nav1.MoveToParent ();
			for (int i = depth2; i > common; i--)
				nav2.MoveToParent ();
			while (!nav1.IsSamePosition (nav2)) {
				nav1.MoveToParent ();
				nav2.MoveToParent ();
				common--;
			}

			// For each this and target, move to the node that is 
			// ancestor of the node and child of the common parent.
			nav1.MoveTo (this);
			for (int i = depth1; i > common + 1; i--)
				nav1.MoveToParent ();
			nav2.MoveTo (nav);
			for (int i = depth2; i > common + 1; i--)
				nav2.MoveToParent ();

			// Those children of common parent are comparable.
			// namespace nodes precede to attributes, and they
			// precede to other nodes.
			if (nav1.NodeType == XPathNodeType.Namespace) {
				if (nav2.NodeType != XPathNodeType.Namespace)
					return XmlNodeOrder.Before;
				while (nav1.MoveToNextNamespace ())
					if (nav1.IsSamePosition (nav2))
						return XmlNodeOrder.Before;
				return XmlNodeOrder.After;
			}
			if (nav2.NodeType == XPathNodeType.Namespace)
				return XmlNodeOrder.After;
			if (nav1.NodeType == XPathNodeType.Attribute) {
				if (nav2.NodeType != XPathNodeType.Attribute)
					return XmlNodeOrder.Before;
				while (nav1.MoveToNextAttribute ())
					if (nav1.IsSamePosition (nav2))
						return XmlNodeOrder.Before;
				return XmlNodeOrder.After;
			}
			while (nav1.MoveToNext ())
				if (nav1.IsSamePosition (nav2))
					return XmlNodeOrder.Before;
			return XmlNodeOrder.After;
		}
예제 #2
0
        public virtual XmlNodeOrder ComparePosition(XPathNavigator nav)
        {
            if (IsSamePosition(nav))
            {
                return(XmlNodeOrder.Same);
            }

            // quick check for direct descendant
            if (IsDescendant(nav))
            {
                return(XmlNodeOrder.Before);
            }

            // quick check for direct ancestor
            if (nav.IsDescendant(this))
            {
                return(XmlNodeOrder.After);
            }

            XPathNavigator nav1 = Clone();
            XPathNavigator nav2 = nav.Clone();

            // check if document instance is the same.
            nav1.MoveToRoot();
            nav2.MoveToRoot();
            if (!nav1.IsSamePosition(nav2))
            {
                return(XmlNodeOrder.Unknown);
            }
            nav1.MoveTo(this);
            nav2.MoveTo(nav);

            int depth1 = 0;

            while (nav1.MoveToParent())
            {
                depth1++;
            }
            nav1.MoveTo(this);
            int depth2 = 0;

            while (nav2.MoveToParent())
            {
                depth2++;
            }
            nav2.MoveTo(nav);

            // find common parent depth
            int common = depth1;

            for (; common > depth2; common--)
            {
                nav1.MoveToParent();
            }
            for (int i = depth2; i > common; i--)
            {
                nav2.MoveToParent();
            }
            while (!nav1.IsSamePosition(nav2))
            {
                nav1.MoveToParent();
                nav2.MoveToParent();
                common--;
            }

            // For each this and target, move to the node that is
            // ancestor of the node and child of the common parent.
            nav1.MoveTo(this);
            for (int i = depth1; i > common + 1; i--)
            {
                nav1.MoveToParent();
            }
            nav2.MoveTo(nav);
            for (int i = depth2; i > common + 1; i--)
            {
                nav2.MoveToParent();
            }

            // Those children of common parent are comparable.
            // namespace nodes precede to attributes, and they
            // precede to other nodes.
            if (nav1.NodeType == XPathNodeType.Namespace)
            {
                if (nav2.NodeType != XPathNodeType.Namespace)
                {
                    return(XmlNodeOrder.Before);
                }
                while (nav1.MoveToNextNamespace())
                {
                    if (nav1.IsSamePosition(nav2))
                    {
                        return(XmlNodeOrder.Before);
                    }
                }
                return(XmlNodeOrder.After);
            }
            if (nav2.NodeType == XPathNodeType.Namespace)
            {
                return(XmlNodeOrder.After);
            }
            if (nav1.NodeType == XPathNodeType.Attribute)
            {
                if (nav2.NodeType != XPathNodeType.Attribute)
                {
                    return(XmlNodeOrder.Before);
                }
                while (nav1.MoveToNextAttribute())
                {
                    if (nav1.IsSamePosition(nav2))
                    {
                        return(XmlNodeOrder.Before);
                    }
                }
                return(XmlNodeOrder.After);
            }
            while (nav1.MoveToNext())
            {
                if (nav1.IsSamePosition(nav2))
                {
                    return(XmlNodeOrder.Before);
                }
            }
            return(XmlNodeOrder.After);
        }
예제 #3
0
        internal override XPathNavigator advance()
        {
            if (_eLast == null)
            {
                XPathNavigator temp = null;
                _eLast = m_qyInput.advance();
                if (_eLast == null)
                {
                    return(null);
                }

                while (_eLast != null)
                {
                    _eLast = _eLast.Clone();
                    temp   = _eLast;
                    _eLast = m_qyInput.advance();
                    if (!temp.IsDescendant(_eLast))
                    {
                        break;
                    }
                }
                _eLast = temp;
            }
            while (true)
            {
                if (_first)
                {
                    _first = false;
                    if (_eLast.NodeType == XPathNodeType.Attribute || _eLast.NodeType == XPathNodeType.Namespace)
                    {
                        _eLast.MoveToParent();
                        if (_fMatchName)
                        {
                            _qy = _eLast.SelectDescendants(m_Name, m_URN, false);
                        }
                        else
                        {
                            _qy = _eLast.SelectDescendants(m_Type, false);
                        }
                    }
                    else
                    {
                        while (true)
                        {
                            if (!_eLast.MoveToNext())
                            {
                                if (!_eLast.MoveToParent())
                                {
                                    _first = true;
                                    return(null);
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                        if (_fMatchName)
                        {
                            _qy = _eLast.SelectDescendants(m_Name, m_URN, true);
                        }
                        else
                        {
                            _qy = _eLast.SelectDescendants(m_Type, true);
                        }
                    }
                }
                if (_qy.MoveNext())
                {
                    _position++;
                    m_eNext = _qy.Current;
                    return(m_eNext);
                }
                else
                {
                    _first = true;
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Position this iterator to the next following node.  Prune by finding the first input node in
        /// document order that has no other input nodes in its subtree.  All other input nodes should be
        /// discarded.  Return IteratorResult.NeedInputNode if the next input node needs to be fetched
        /// first.  Return IteratorResult.HaveCurrent if the Current property is set to the next node in the
        /// iteration.
        /// </summary>
        public IteratorResult MoveNext(XPathNavigator input)
        {
            switch (_state)
            {
                case IteratorState.NeedCandidateCurrent:
                    // If there are no more input nodes, then iteration is complete
                    if (input == null)
                        return IteratorResult.NoMoreNodes;

                    // Save input node as current node
                    _navCurrent = XmlQueryRuntime.SyncToNavigator(_navCurrent, input);

                    // Still must check next input node to see if is a descendant of this one
                    _state = IteratorState.HaveCandidateCurrent;
                    return IteratorResult.NeedInputNode;

                case IteratorState.HaveCandidateCurrent:
                    // If there are no more input nodes,
                    if (input == null)
                    {
                        // Then candidate node has been selected, and there are no further input nodes
                        _state = IteratorState.HaveCurrentNoNext;
                        return MoveFirst();
                    }

                    // If input node is in the subtree of the candidate node, then use the input node instead
                    if (_navCurrent.IsDescendant(input))
                        goto case IteratorState.NeedCandidateCurrent;

                    // Found node on which to perform following scan.  Now skip past all input nodes in the same document.
                    _state = IteratorState.HaveCurrentNeedNext;
                    goto case IteratorState.HaveCurrentNeedNext;

                case IteratorState.HaveCurrentNeedNext:
                    // If there are no more input nodes,
                    if (input == null)
                    {
                        // Then candidate node has been selected, and there are no further input nodes
                        _state = IteratorState.HaveCurrentNoNext;
                        return MoveFirst();
                    }

                    // Skip input node unless it's in a different document than the node on which the following scan was performed
                    if (_navCurrent.ComparePosition(input) != XmlNodeOrder.Unknown)
                        return IteratorResult.NeedInputNode;

                    // Next node is in a different document, so save it
                    _navNext = XmlQueryRuntime.SyncToNavigator(_navNext, input);
                    _state = IteratorState.HaveCurrentHaveNext;
                    return MoveFirst();
            }

            if (!_filter.MoveToFollowing(_navCurrent, null))
                return MoveFailed();

            return IteratorResult.HaveCurrentNode;
        }
예제 #5
0
		private void IsDescendant (XPathNavigator nav)
		{
			XPathNavigator tmp = nav.Clone ();
			XPathNodeIterator iter = nav.Select ("//e");
			iter.MoveNext ();
			Assert.IsTrue (nav.MoveTo (iter.Current), "#1");
			Assert.IsTrue (nav.MoveToFirstAttribute (), "#2");
			Assert.AreEqual ("attr", nav.Name, "#3");
			Assert.AreEqual ("", tmp.Name, "#4");
			Assert.IsTrue (tmp.IsDescendant (nav), "#5");
			Assert.IsTrue (!nav.IsDescendant (tmp), "#6");
			tmp.MoveToFirstChild ();
			Assert.AreEqual ("a", tmp.Name, "#7");
			Assert.IsTrue (tmp.IsDescendant (nav), "#8");
			Assert.IsTrue (!nav.IsDescendant (tmp), "#9");
			tmp.MoveTo (iter.Current);
			Assert.AreEqual ("e", tmp.Name, "#10");
			Assert.IsTrue (tmp.IsDescendant (nav), "#11");
			Assert.IsTrue (!nav.IsDescendant (tmp), "#12");
		}
	public virtual XmlNodeOrder ComparePosition(XPathNavigator nav)
			{
				if(IsSamePosition(nav))
				{
					return XmlNodeOrder.Same;
				}

				if(IsDescendant(nav))
				{
					return XmlNodeOrder.Before;
				}
				else if(nav.IsDescendant(this))
				{
					return XmlNodeOrder.After;
				}
				
				XPathNavigator copy = this.Clone();
				XPathNavigator other = nav.Clone();
				
				/* now, it gets expensive - we find the 
				   closest common ancestor. But these two
				   might be from totally different places.
				   
				   Someone should re-implement this somewhere,
				   so that it is faster for XmlDocument.
				 */
				int common = 0;
				int otherDepth = 0;
				int copyDepth = 0;
				
				copy.MoveToRoot();
				other.MoveToRoot();

				if(!copy.IsSamePosition(other))
				{
					return XmlNodeOrder.Unknown;
				}

				/* what do you think ? I'm made of GC space ? */
				copy.MoveTo(this);
				other.MoveTo(nav);	

				while(other.MoveToParent())
				{
					otherDepth++;
				}

				while(copy.MoveToParent())
				{
					copyDepth++;
				}

				common = (otherDepth > copyDepth) ? copyDepth : otherDepth;

				other.MoveTo(nav);
				copy.MoveTo(this);

				// traverse both till you get to depth == common
				for(;otherDepth > common; otherDepth--)
				{
					other.MoveToParent();
				}
				for(;copyDepth > common; copyDepth--)
				{
					copy.MoveToParent();
				}

				other.MoveTo(nav);
				copy.MoveTo(this);

				XPathNavigator copy1 = copy.Clone();
				XPathNavigator other1 = other.Clone();

				while(copy.IsSamePosition(other))
				{
					copy1.MoveTo(copy);
					other1.MoveTo(other);

					copy.MoveToParent();
					other.MoveToParent();
				}

				copy.MoveTo(copy1);
				other.MoveTo(other1);

				// Now copy & other are siblings and can be compared
				while(copy.MoveToNext())
				{
					if(copy.IsSamePosition(other))
					{
						return XmlNodeOrder.Before;
					}
				}

				return XmlNodeOrder.After;
			}
		private void IsDescendant (XPathNavigator nav)
		{
			XPathNavigator tmp = nav.Clone ();
			XPathNodeIterator iter = nav.Select ("//e");
			iter.MoveNext ();
			Assert (nav.MoveTo (iter.Current));
			Assert (nav.MoveToFirstAttribute ());
			AssertEquals ("attr", nav.Name);
			AssertEquals ("", tmp.Name);
			Assert (tmp.IsDescendant (nav));
			Assert (!nav.IsDescendant (tmp));
			tmp.MoveToFirstChild ();
			AssertEquals ("a", tmp.Name);
			Assert (tmp.IsDescendant (nav));
			Assert (!nav.IsDescendant (tmp));
			tmp.MoveTo (iter.Current);
			AssertEquals ("e", tmp.Name);
			Assert (tmp.IsDescendant (nav));
			Assert (!nav.IsDescendant (tmp));
		}
예제 #8
0
        public virtual XmlNodeOrder ComparePosition(XPathNavigator nav)
        {
            if (IsSamePosition(nav))
            {
                return(XmlNodeOrder.Same);
            }

            if (IsDescendant(nav))
            {
                return(XmlNodeOrder.Before);
            }
            else if (nav.IsDescendant(this))
            {
                return(XmlNodeOrder.After);
            }

            XPathNavigator copy  = this.Clone();
            XPathNavigator other = nav.Clone();

            /* now, it gets expensive - we find the
             * closest common ancestor. But these two
             * might be from totally different places.
             *
             * Someone should re-implement this somewhere,
             * so that it is faster for XmlDocument.
             */
            int common     = 0;
            int otherDepth = 0;
            int copyDepth  = 0;

            copy.MoveToRoot();
            other.MoveToRoot();

            if (!copy.IsSamePosition(other))
            {
                return(XmlNodeOrder.Unknown);
            }

            /* what do you think ? I'm made of GC space ? */
            copy.MoveTo(this);
            other.MoveTo(nav);

            while (other.MoveToParent())
            {
                otherDepth++;
            }

            while (copy.MoveToParent())
            {
                copyDepth++;
            }

            common = (otherDepth > copyDepth) ? copyDepth : otherDepth;

            other.MoveTo(nav);
            copy.MoveTo(this);

            // traverse both till you get to depth == common
            for (; otherDepth > common; otherDepth--)
            {
                other.MoveToParent();
            }
            for (; copyDepth > common; copyDepth--)
            {
                copy.MoveToParent();
            }

            other.MoveTo(nav);
            copy.MoveTo(this);

            XPathNavigator copy1  = copy.Clone();
            XPathNavigator other1 = other.Clone();

            while (copy.IsSamePosition(other))
            {
                copy1.MoveTo(copy);
                other1.MoveTo(other);

                copy.MoveToParent();
                other.MoveToParent();
            }

            copy.MoveTo(copy1);
            other.MoveTo(other1);

            // Now copy & other are siblings and can be compared
            while (copy.MoveToNext())
            {
                if (copy.IsSamePosition(other))
                {
                    return(XmlNodeOrder.Before);
                }
            }

            return(XmlNodeOrder.After);
        }