File: System\Xml\XPath\Internal\FollowingQuery.cs
Web Access
Project: src\src\libraries\System.Private.Xml\src\System.Private.Xml.csproj (System.Private.Xml)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Diagnostics;
using System.Xml.XPath;
 
namespace MS.Internal.Xml.XPath
{
    internal sealed class FollowingQuery : BaseAxisQuery
    {
        private XPathNavigator? _input;
        private XPathNodeIterator? _iterator;
 
        public FollowingQuery(Query qyInput, string name, string prefix, XPathNodeType typeTest) : base(qyInput, name, prefix, typeTest) { }
        private FollowingQuery(FollowingQuery other) : base(other)
        {
            _input = Clone(other._input);
            _iterator = Clone(other._iterator);
        }
 
        public override void Reset()
        {
            _iterator = null;
            base.Reset();
        }
 
        public override XPathNavigator? Advance()
        {
            if (_iterator == null)
            {
                _input = qyInput.Advance();
                if (_input == null)
                {
                    return null;
                }
 
                XPathNavigator prev;
                do
                {
                    prev = _input.Clone();
                    _input = qyInput.Advance();
                } while (prev.IsDescendant(_input));
                _input = prev;
 
                _iterator = XPathEmptyIterator.Instance;
            }
 
            while (!_iterator.MoveNext())
            {
                bool matchSelf;
                if (_input!.NodeType == XPathNodeType.Attribute || _input.NodeType == XPathNodeType.Namespace)
                {
                    _input.MoveToParent();
                    matchSelf = false;
                }
                else
                {
                    while (!_input.MoveToNext())
                    {
                        if (!_input.MoveToParent())
                        {
                            return null;
                        }
                    }
                    matchSelf = true;
                }
                if (NameTest)
                {
                    _iterator = _input.SelectDescendants(Name, Namespace!, matchSelf);
                }
                else
                {
                    _iterator = _input.SelectDescendants(TypeTest, matchSelf);
                }
            }
            position++;
            currentNode = _iterator.Current;
            return currentNode;
        }
 
        public override XPathNodeIterator Clone() { return new FollowingQuery(this); }
    }
}