2 // System.Xml.XPath.BaseIterator
5 // Piers Haken (piersh@friskit.com)
6 // Atsushi Enomoto (atsushi@ximian.com)
8 // (C) 2002 Piers Haken
9 // (C) 2003 Atsushi Enomoto
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System.Collections;
36 using System.Xml.XPath;
40 using NSResolver = System.Xml.IXmlNamespaceResolver;
42 using NSResolver = System.Xml.XmlNamespaceManager;
45 namespace System.Xml.XPath
47 internal abstract class BaseIterator : XPathNodeIterator
52 internal BaseIterator (BaseIterator other)
55 position = other.position;
57 internal BaseIterator (NSResolver nsm)
62 public NSResolver NamespaceManager
68 public virtual bool ReverseAxis {
72 public int ComparablePosition {
75 int diff = Count - CurrentPosition + 1;
76 return diff < 1 ? 1 : diff;
79 return CurrentPosition;
83 public override int CurrentPosition {
84 get { return position; }
87 public override bool MoveNext ()
95 public abstract bool MoveNextCore ();
97 public override string ToString ()
100 return Current.NodeType.ToString () + "[" + CurrentPosition + "] : " + Current.Name + " = " + Current.Value;
102 return this.GetType().ToString () + "[" + CurrentPosition + "]";
106 internal class WrapperIterator : BaseIterator
108 XPathNodeIterator iter;
110 public WrapperIterator (XPathNodeIterator iter, NSResolver nsm)
116 private WrapperIterator (WrapperIterator other)
119 iter = other.iter.Clone ();
122 public override XPathNodeIterator Clone ()
124 return new WrapperIterator (this);
127 public override bool MoveNextCore ()
129 return iter.MoveNext ();
132 public override XPathNavigator Current {
133 get { return iter.Current; }
137 internal abstract class SimpleIterator : BaseIterator
139 protected readonly XPathNavigator _nav;
140 protected XPathNavigator _current;
142 public SimpleIterator (BaseIterator iter) : base (iter.NamespaceManager)
144 _nav = iter.Current.Clone ();
146 protected SimpleIterator (SimpleIterator other, bool clone) : base (other)
148 _nav = other._nav.Clone ();
150 public SimpleIterator (XPathNavigator nav, NSResolver nsm) : base (nsm)
155 public override XPathNavigator Current {
157 if (_current == null) // position == 0
158 _current = _nav.Clone ();
164 internal class SelfIterator : SimpleIterator
166 public SelfIterator (BaseIterator iter) : base (iter) {}
167 public SelfIterator (XPathNavigator nav, NSResolver nsm) : base (nav, nsm) {}
168 protected SelfIterator (SelfIterator other, bool clone) : base (other, true)
172 public override XPathNodeIterator Clone () { return new SelfIterator (this, true); }
173 public override bool MoveNextCore ()
175 if (CurrentPosition == 0)
182 public override XPathNavigator Current {
187 internal class NullIterator : SelfIterator
189 public NullIterator (BaseIterator iter) : base (iter) {}
190 public NullIterator (XPathNavigator nav) : this (nav, null) {}
191 public NullIterator (XPathNavigator nav, NSResolver nsm) : base (nav, nsm) {}
192 private NullIterator (NullIterator other) : base (other, true) {}
193 public override XPathNodeIterator Clone () { return new NullIterator (this); }
194 public override bool MoveNextCore ()
200 internal class ParensIterator : BaseIterator
204 public ParensIterator (BaseIterator iter) : base (iter.NamespaceManager)
208 private ParensIterator (ParensIterator other) : base (other)
210 _iter = (BaseIterator) other._iter.Clone ();
212 public override XPathNodeIterator Clone () { return new ParensIterator (this); }
213 public override bool MoveNextCore ()
215 return _iter.MoveNext ();
218 public override XPathNavigator Current { get { return _iter.Current; }}
220 public override int Count { get { return _iter.Count; } }
223 internal class ParentIterator : SimpleIterator
226 public ParentIterator (BaseIterator iter) : base (iter)
228 canMove = _nav.MoveToParent ();
231 private ParentIterator (ParentIterator other, bool dummy) : base (other, true)
234 canMove = other.canMove;
236 public ParentIterator (XPathNavigator nav, NSResolver nsm) : base (nav, nsm) {}
237 public override XPathNodeIterator Clone () { return new ParentIterator (this, true); }
238 public override bool MoveNextCore ()
247 internal class ChildIterator : SimpleIterator
249 public ChildIterator (BaseIterator iter) : base (iter) {}
250 private ChildIterator (ChildIterator other) : base (other, true) {}
251 public override XPathNodeIterator Clone () { return new ChildIterator (this); }
252 public override bool MoveNextCore ()
254 bool fSuccess = (CurrentPosition == 0) ? _nav.MoveToFirstChild () : _nav.MoveToNext ();
256 Current.MoveTo (_nav);
262 internal class FollowingSiblingIterator : SimpleIterator
264 public FollowingSiblingIterator (BaseIterator iter) : base (iter) {}
265 private FollowingSiblingIterator (FollowingSiblingIterator other) : base (other, true) {}
266 public override XPathNodeIterator Clone () { return new FollowingSiblingIterator (this); }
267 public override bool MoveNextCore ()
269 switch (_nav.NodeType) {
270 case XPathNodeType.Attribute:
271 case XPathNodeType.Namespace:
272 // They have no siblings.
275 if (_nav.MoveToNext ())
277 Current.MoveTo (_nav);
284 internal class PrecedingSiblingIterator : SimpleIterator
288 XPathNavigator startPosition;
290 public PrecedingSiblingIterator (BaseIterator iter) : base (iter)
292 startPosition = iter.Current.Clone ();
294 private PrecedingSiblingIterator (PrecedingSiblingIterator other) : base (other, true)
296 startPosition = other.startPosition;
297 started = other.started;
298 finished = other.finished;
301 public override XPathNodeIterator Clone () { return new PrecedingSiblingIterator (this); }
302 public override bool MoveNextCore ()
308 switch (_nav.NodeType) {
309 case XPathNodeType.Attribute:
310 case XPathNodeType.Namespace:
311 // They have no siblings.
317 if (!_nav.IsSamePosition (startPosition)) {
318 Current.MoveTo (_nav);
322 if (!_nav.MoveToNext ()) {
327 if (_nav.ComparePosition (startPosition) != XmlNodeOrder.Before) {
328 // Note that if _nav contains only 1 node, it won't be Same.
332 Current.MoveTo (_nav);
336 public override bool ReverseAxis {
341 internal class AncestorIterator : SimpleIterator
344 ArrayList navigators;
345 XPathNavigator startPosition;
347 public AncestorIterator (BaseIterator iter) : base (iter)
349 startPosition = iter.Current.Clone ();
352 private AncestorIterator (AncestorIterator other)
355 startPosition = other.startPosition;
356 if (other.navigators != null)
357 navigators = (ArrayList) other.navigators;
358 currentPosition = other.currentPosition;
361 public override XPathNodeIterator Clone ()
363 return new AncestorIterator (this);
366 private void CollectResults ()
368 navigators = new ArrayList ();
370 XPathNavigator ancestors = startPosition.Clone ();
371 if (!ancestors.MoveToParent ())
373 while (ancestors.NodeType != XPathNodeType.Root) {
374 navigators.Add (ancestors.Clone ());
375 ancestors.MoveToParent ();
377 currentPosition = navigators.Count;
380 public override bool MoveNextCore ()
382 if (navigators == null) {
384 if (startPosition.NodeType != XPathNodeType.Root) {
385 // First time it returns Root
387 Current.MoveTo (_nav);
391 if (currentPosition == 0)
393 _nav.MoveTo ((XPathNavigator) navigators [--currentPosition]);
394 Current.MoveTo (_nav);
398 public override bool ReverseAxis {
402 public override int Count {
404 if (navigators == null)
406 return navigators.Count;
411 internal class AncestorOrSelfIterator : SimpleIterator
414 ArrayList navigators;
415 XPathNavigator startPosition;
417 public AncestorOrSelfIterator (BaseIterator iter) : base (iter)
419 startPosition = iter.Current.Clone ();
422 private AncestorOrSelfIterator (AncestorOrSelfIterator other)
425 startPosition = other.startPosition;
426 if (other.navigators != null)
427 navigators = (ArrayList) other.navigators.Clone ();
428 currentPosition = other.currentPosition;
431 public override XPathNodeIterator Clone ()
433 return new AncestorOrSelfIterator (this);
436 private void CollectResults ()
438 navigators = new ArrayList ();
440 XPathNavigator ancestors = startPosition.Clone ();
441 if (!ancestors.MoveToParent ())
443 while (ancestors.NodeType != XPathNodeType.Root) {
444 navigators.Add (ancestors.Clone ());
445 ancestors.MoveToParent ();
447 currentPosition = navigators.Count;
450 public override bool MoveNextCore ()
452 if (navigators == null) {
454 if (startPosition.NodeType != XPathNodeType.Root) {
455 // First time it returns Root
457 Current.MoveTo (_nav);
461 if (currentPosition == -1)
463 if (currentPosition-- == 0) {
464 _nav.MoveTo (startPosition);
465 Current.MoveTo (_nav);
466 return true; // returns self.
468 _nav.MoveTo ((XPathNavigator) navigators [currentPosition]);
469 Current.MoveTo (_nav);
473 public override bool ReverseAxis {
477 public override int Count {
479 if (navigators == null)
481 return navigators.Count + 1;
486 internal class DescendantIterator : SimpleIterator
489 private bool _finished;
491 public DescendantIterator (BaseIterator iter) : base (iter) {}
493 private DescendantIterator (DescendantIterator other) : base (other)
495 _depth = other._depth;
496 _finished = other._finished;
499 public override XPathNodeIterator Clone () { return new DescendantIterator (this); }
501 public override bool MoveNextCore ()
506 if (_nav.MoveToFirstChild ())
509 Current.MoveTo (_nav);
514 if (_nav.MoveToNext ())
516 Current.MoveTo (_nav);
519 if (!_nav.MoveToParent ()) // should NEVER fail!
520 throw new XPathException ("Current node is removed while it should not be, or there are some bugs in the XPathNavigator implementation class: " + _nav.GetType ());
528 internal class DescendantOrSelfIterator : SimpleIterator
531 private bool _finished;
533 public DescendantOrSelfIterator (BaseIterator iter) : base (iter) {}
535 private DescendantOrSelfIterator (DescendantOrSelfIterator other) : base (other, true)
537 _depth = other._depth;
540 public override XPathNodeIterator Clone () { return new DescendantOrSelfIterator (this); }
542 public override bool MoveNextCore ()
547 if (CurrentPosition == 0)
550 Current.MoveTo (_nav);
553 if (_nav.MoveToFirstChild ())
556 Current.MoveTo (_nav);
561 if (_nav.MoveToNext ())
563 Current.MoveTo (_nav);
566 if (!_nav.MoveToParent ()) // should NEVER fail!
567 throw new XPathException ("Current node is removed while it should not be, or there are some bugs in the XPathNavigator implementation class: " + _nav.GetType ());
575 internal class FollowingIterator : SimpleIterator
577 private bool _finished = false;
578 public FollowingIterator (BaseIterator iter) : base (iter) {}
579 private FollowingIterator (FollowingIterator other) : base (other, true) {}
580 public override XPathNodeIterator Clone () { return new FollowingIterator (this); }
581 public override bool MoveNextCore ()
585 bool checkChildren = true;
586 if (CurrentPosition == 0)
588 checkChildren = false;
589 switch (_nav.NodeType) {
590 case XPathNodeType.Attribute:
591 case XPathNodeType.Namespace:
592 _nav.MoveToParent ();
593 checkChildren = true;
596 if (_nav.MoveToNext ())
598 Current.MoveTo (_nav);
601 while (_nav.MoveToParent ()) {
602 if (_nav.MoveToNext ()) {
603 Current.MoveTo (_nav);
613 if (_nav.MoveToFirstChild ())
615 Current.MoveTo (_nav);
620 if (_nav.MoveToNext ())
622 Current.MoveTo (_nav);
626 while (_nav.MoveToParent ());
633 internal class PrecedingIterator : SimpleIterator
637 XPathNavigator startPosition;
639 public PrecedingIterator (BaseIterator iter) : base (iter)
641 startPosition = iter.Current.Clone ();
643 private PrecedingIterator (PrecedingIterator other) : base (other, true)
645 startPosition = other.startPosition;
646 started = other.started;
647 finished = other.finished;
649 public override XPathNodeIterator Clone () { return new PrecedingIterator (this); }
650 public override bool MoveNextCore ()
660 while (!_nav.MoveToFirstChild ()) {
661 while (!_nav.MoveToNext ()) {
662 if (!_nav.MoveToParent ()) { // Should not finish, at least before startPosition.
669 if (_nav.IsDescendant (startPosition))
674 if (_nav.ComparePosition (startPosition) != XmlNodeOrder.Before) {
675 // Note that if _nav contains only 1 node, it won't be Same.
679 Current.MoveTo (_nav);
683 public override bool ReverseAxis {
688 internal class NamespaceIterator : SimpleIterator
690 public NamespaceIterator (BaseIterator iter) : base (iter) {}
691 private NamespaceIterator (NamespaceIterator other) : base (other, true) {}
692 public override XPathNodeIterator Clone () { return new NamespaceIterator (this); }
693 public override bool MoveNextCore ()
695 if (CurrentPosition == 0)
697 if (_nav.MoveToFirstNamespace ())
699 Current.MoveTo (_nav);
703 else if (_nav.MoveToNextNamespace ())
705 Current.MoveTo (_nav);
712 internal class AttributeIterator : SimpleIterator
714 public AttributeIterator (BaseIterator iter) : base (iter) {}
715 private AttributeIterator (AttributeIterator other) : base (other, true) {}
716 public override XPathNodeIterator Clone () { return new AttributeIterator (this); }
717 public override bool MoveNextCore ()
719 if (CurrentPosition == 0)
721 if (_nav.MoveToFirstAttribute ())
723 Current.MoveTo (_nav);
727 else if (_nav.MoveToNextAttribute ())
729 Current.MoveTo (_nav);
736 internal class AxisIterator : BaseIterator
738 private SimpleIterator _iter;
739 private NodeTest _test;
742 //XPathNodeType matchType;
744 public AxisIterator (SimpleIterator iter, NodeTest test) : base (iter.NamespaceManager)
748 //test.GetInfo (out name, out ns, out matchType, NamespaceManager);
750 // name = Current.NameTable.Add (name);
753 // ns = Current.NameTable.Add (ns);
756 private AxisIterator (AxisIterator other) : base (other)
758 _iter = (SimpleIterator) other._iter.Clone ();
762 //matchType = other.matchType;
764 public override XPathNodeIterator Clone () { return new AxisIterator (this); }
766 public override bool MoveNextCore ()
768 while (_iter.MoveNext ())
770 if (_test.Match (NamespaceManager, Current))
777 public override XPathNavigator Current { get { return _iter.Current; }}
779 public override bool ReverseAxis {
780 get { return _iter.ReverseAxis; }
784 internal class SimpleSlashIterator : BaseIterator
786 private NodeSet _expr;
787 private BaseIterator _left, _right;
788 private XPathNavigator _current;
790 public SimpleSlashIterator (BaseIterator left, NodeSet expr)
791 : base (left.NamespaceManager)
797 private SimpleSlashIterator (SimpleSlashIterator other)
801 _left = (BaseIterator) other._left.Clone ();
802 if (other._right != null)
803 _right = (BaseIterator) other._right.Clone ();
806 public override XPathNodeIterator Clone () { return new SimpleSlashIterator (this); }
808 public override bool MoveNextCore ()
810 while (_right == null || !_right.MoveNext ()) {
811 if (!_left.MoveNext ())
813 _right = _expr.EvaluateNodeSet (_left);
815 if (_current == null)
816 _current = _right.Current.Clone ();
818 if (! _current.MoveTo (_right.Current) )
819 _current = _right.Current.Clone ();
823 public override XPathNavigator Current {
824 get { return _current; }
828 internal class SlashIterator : BaseIterator
830 private BaseIterator _iterLeft;
831 private BaseIterator _iterRight;
832 private NodeSet _expr;
834 SortedList _iterList;
836 BaseIterator _nextIterRight;
838 public SlashIterator (BaseIterator iter, NodeSet expr, bool requireSorting) : base (iter.NamespaceManager)
847 private SlashIterator (SlashIterator other) : base (other)
849 _iterLeft = (BaseIterator) other._iterLeft.Clone ();
850 if (other._iterRight != null)
851 _iterRight = (BaseIterator) other._iterRight.Clone ();
853 if (other._iterList != null)
854 _iterList = (SortedList) other._iterList.Clone ();
855 if (other._navStore != null)
856 _navStore = (ArrayList) other._navStore.Clone ();
857 _finished = other._finished;
858 if (other._nextIterRight != null)
859 _nextIterRight = (BaseIterator) other._nextIterRight.Clone ();
861 public override XPathNodeIterator Clone () { return new SlashIterator (this); }
863 public override bool MoveNextCore ()
867 if (_navStore != null) {
868 // Which requires sorting::
869 if (_navStore.Count < CurrentPosition + 1) {
873 while (_navStore.Count > CurrentPosition + 1) {
874 if (((XPathNavigator) _navStore [CurrentPosition + 1]).IsSamePosition (
875 (XPathNavigator) _navStore [CurrentPosition]))
876 _navStore.RemoveAt (CurrentPosition + 1);
883 // Which does not require sorting::
885 if (_iterRight == null) { // First time
886 if (!_iterLeft.MoveNext ())
888 _iterRight = _expr.EvaluateNodeSet (_iterLeft);
889 _iterList = new SortedList (XPathIteratorComparer.Instance);
893 while (!_iterRight.MoveNext ()) {
894 if (_iterList.Count > 0) {
895 int last = _iterList.Count - 1;
896 _iterRight = (BaseIterator) _iterList.GetByIndex (last);
897 _iterList.RemoveAt (last);
899 } else if (_nextIterRight != null) {
900 _iterRight = _nextIterRight;
901 _nextIterRight = null;
903 } else if (!_iterLeft.MoveNext ()) {
908 _iterRight = _expr.EvaluateNodeSet (_iterLeft);
913 if (_nextIterRight == null) {
914 bool noMoreNext = false;
915 while (_nextIterRight == null || !_nextIterRight.MoveNext ()) {
916 if(_iterLeft.MoveNext ())
917 _nextIterRight = _expr.EvaluateNodeSet (_iterLeft);
924 _nextIterRight = null; // FIXME: More efficient code. Maybe making noMoreNext class scope would be better.
926 if (_nextIterRight != null) {
927 switch (_iterRight.Current.ComparePosition (_nextIterRight.Current)) {
928 case XmlNodeOrder.After:
929 _iterList [_iterRight] = _iterRight;
930 _iterRight = _nextIterRight;
931 _nextIterRight = null;
934 case XmlNodeOrder.Same:
935 if (!_nextIterRight.MoveNext ())
936 _nextIterRight = null;
939 int last = _iterList.Count;
940 _iterList [_nextIterRight] = _nextIterRight;
941 if (last != _iterList.Count) {
942 _nextIterRight = (BaseIterator) _iterList.GetByIndex (last);
943 _iterList.RemoveAt (last);
956 private void CollectResults ()
958 _navStore = new ArrayList ();
960 while (_iterRight == null || !_iterRight.MoveNext ()) {
961 if (!_iterLeft.MoveNext ()) {
962 _navStore.Sort (XPathNavigatorComparer.Instance);
965 _iterRight = _expr.EvaluateNodeSet (_iterLeft);
967 XPathNavigator nav = _iterRight.Current;
968 _navStore.Add (nav.Clone ());
972 public override XPathNavigator Current {
974 if (CurrentPosition <= 0) return null;
975 if (_navStore != null) {
976 return (XPathNavigator) _navStore [CurrentPosition - 1];
978 return _iterRight.Current;
983 public override int Count { get { return _navStore == null ? base.Count : _navStore.Count; } }
986 internal class PredicateIterator : BaseIterator
988 private BaseIterator _iter;
989 private Expression _pred;
990 private XPathResultType resType;
991 private bool finished;
993 public PredicateIterator (BaseIterator iter, Expression pred) : base (iter.NamespaceManager)
997 resType = pred.GetReturnType (iter);
1000 private PredicateIterator (PredicateIterator other) : base (other)
1002 _iter = (BaseIterator) other._iter.Clone ();
1003 _pred = other._pred;
1004 resType = other.resType;
1005 finished = other.finished;
1007 public override XPathNodeIterator Clone () { return new PredicateIterator (this); }
1009 public override bool MoveNextCore ()
1013 while (_iter.MoveNext ())
1016 case XPathResultType.Number:
1017 if (_pred.EvaluateNumber (_iter) != _iter.ComparablePosition)
1021 case XPathResultType.Any: {
1022 object result = _pred.Evaluate (_iter);
1023 if (result is double)
1025 if ((double) result != _iter.ComparablePosition)
1029 else if (!XPathFunctions.ToBoolean (result))
1034 if (!_pred.EvaluateBoolean (_iter))
1043 public override XPathNavigator Current { get { return _iter.Current; }}
1044 public override bool ReverseAxis {
1045 get { return _iter.ReverseAxis; }
1049 internal class ListIterator : BaseIterator
1051 private IList _list;
1053 public ListIterator (BaseIterator iter, IList list) : base (iter.NamespaceManager)
1058 public ListIterator (IList list, NSResolver nsm) : base (nsm)
1063 private ListIterator (ListIterator other) : base (other)
1065 _list = other._list;
1067 public override XPathNodeIterator Clone () { return new ListIterator (this); }
1069 public override bool MoveNextCore ()
1071 if (CurrentPosition >= _list.Count)
1075 public override XPathNavigator Current {
1077 if (_list.Count == 0)
1079 return (XPathNavigator) _list [CurrentPosition - 1];
1083 public override int Count { get { return _list.Count; } }
1087 internal class UnionIterator : BaseIterator
1089 private BaseIterator _left, _right;
1090 private bool keepLeft;
1091 private bool keepRight;
1092 XPathNavigator _current;
1094 public UnionIterator (BaseIterator iter, BaseIterator left, BaseIterator right) : base (iter.NamespaceManager)
1100 private UnionIterator (UnionIterator other) : base (other)
1102 _left = (BaseIterator) other._left.Clone ();
1103 _right = (BaseIterator) other._right.Clone ();
1104 keepLeft = other.keepLeft;
1105 keepRight = other.keepRight;
1106 if (other._current != null)
1107 _current = other._current.Clone ();
1109 public override XPathNodeIterator Clone () { return new UnionIterator (this); }
1111 public override bool MoveNextCore ()
1114 keepLeft = _left.MoveNext ();
1116 keepRight = _right.MoveNext ();
1118 if (!keepLeft && !keepRight)
1125 } else if (!keepLeft) {
1127 SetCurrent (_right);
1131 switch (_left.Current.ComparePosition (_right.Current)) {
1132 case XmlNodeOrder.Same:
1133 // consume both. i.e. don't output duplicate result.
1134 keepLeft = keepRight = false;
1135 SetCurrent (_right);
1137 case XmlNodeOrder.Before:
1138 case XmlNodeOrder.Unknown: // Maybe happen because of "document(a) | document(b)"
1142 case XmlNodeOrder.After:
1144 SetCurrent (_right);
1147 throw new InvalidOperationException ("Should not happen.");
1151 private void SetCurrent (XPathNodeIterator iter)
1153 if (_current == null)
1154 _current = iter.Current.Clone ();
1156 if (! _current.MoveTo (iter.Current) )
1157 _current = iter.Current.Clone ();
1160 public override XPathNavigator Current
1162 get { return _current; }
1166 internal class OrderedIterator : BaseIterator
1172 public OrderedIterator (BaseIterator iter)
1173 : base (iter.NamespaceManager)
1175 // if (iter.Ordered)
1179 list = new ArrayList ();
1180 while (iter.MoveNext ())
1181 list.Add (iter.Current);
1182 list.Sort (XPathNavigatorComparer.Instance);
1186 private OrderedIterator (OrderedIterator other, bool dummy)
1189 if (other.iter != null)
1190 iter = (BaseIterator) other.iter.Clone ();
1192 index = other.index;
1195 public override XPathNodeIterator Clone ()
1197 return new OrderedIterator (this);
1200 public override bool MoveNextCore ()
1203 return iter.MoveNext ();
1204 else if (index++ < list.Count)
1210 public override XPathNavigator Current {
1211 get { return iter != null ? iter.Current : index < 0 ? null : (XPathNavigator) list [index]; }