1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Xml.XPath; 6 7 namespace MS.Internal.Xml.XPath 8 { 9 internal sealed class FollowingQuery : BaseAxisQuery 10 { 11 private XPathNavigator _input; 12 private XPathNodeIterator _iterator; 13 FollowingQuery(Query qyInput, string name, string prefix, XPathNodeType typeTest)14 public FollowingQuery(Query qyInput, string name, string prefix, XPathNodeType typeTest) : base(qyInput, name, prefix, typeTest) { } FollowingQuery(FollowingQuery other)15 private FollowingQuery(FollowingQuery other) : base(other) 16 { 17 _input = Clone(other._input); 18 _iterator = Clone(other._iterator); 19 } 20 Reset()21 public override void Reset() 22 { 23 _iterator = null; 24 base.Reset(); 25 } 26 Advance()27 public override XPathNavigator Advance() 28 { 29 if (_iterator == null) 30 { 31 _input = qyInput.Advance(); 32 if (_input == null) 33 { 34 return null; 35 } 36 37 XPathNavigator prev; 38 do 39 { 40 prev = _input.Clone(); 41 _input = qyInput.Advance(); 42 } while (prev.IsDescendant(_input)); 43 _input = prev; 44 45 _iterator = XPathEmptyIterator.Instance; 46 } 47 48 while (!_iterator.MoveNext()) 49 { 50 bool matchSelf; 51 if (_input.NodeType == XPathNodeType.Attribute || _input.NodeType == XPathNodeType.Namespace) 52 { 53 _input.MoveToParent(); 54 matchSelf = false; 55 } 56 else 57 { 58 while (!_input.MoveToNext()) 59 { 60 if (!_input.MoveToParent()) 61 { 62 return null; 63 } 64 } 65 matchSelf = true; 66 } 67 if (NameTest) 68 { 69 _iterator = _input.SelectDescendants(Name, Namespace, matchSelf); 70 } 71 else 72 { 73 _iterator = _input.SelectDescendants(TypeTest, matchSelf); 74 } 75 } 76 position++; 77 currentNode = _iterator.Current; 78 return currentNode; 79 } 80 Clone()81 public override XPathNodeIterator Clone() { return new FollowingQuery(this); } 82 } 83 } 84