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 ()
92 if (Current != null &&
93 Current.NodeType == XPathNodeType.Whitespace &&
94 _nsm is XsltContext &&
95 !((XsltContext) _nsm).PreserveWhitespace (Current))
100 public abstract bool MoveNextCore ();
102 public override string ToString ()
105 return Current.NodeType.ToString () + "[" + CurrentPosition + "] : " + Current.Name + " = " + Current.Value;
107 return this.GetType().ToString () + "[" + CurrentPosition + "]";
111 internal class WrapperIterator : BaseIterator
113 XPathNodeIterator iter;
115 public WrapperIterator (XPathNodeIterator iter, NSResolver nsm)
121 private WrapperIterator (WrapperIterator other)
124 iter = other.iter.Clone ();
127 public override XPathNodeIterator Clone ()
129 return new WrapperIterator (this);
132 public override bool MoveNextCore ()
134 return iter.MoveNext ();
137 public override XPathNavigator Current {
138 get { return iter.Current; }
142 internal abstract class SimpleIterator : BaseIterator
144 protected readonly XPathNavigator _nav;
145 protected XPathNavigator _current;
147 public SimpleIterator (BaseIterator iter) : base (iter.NamespaceManager)
149 _nav = iter.Current.Clone ();
151 protected SimpleIterator (SimpleIterator other, bool clone) : base (other)
153 _nav = other._nav.Clone ();
155 public SimpleIterator (XPathNavigator nav, NSResolver nsm) : base (nsm)
160 public override XPathNavigator Current {
162 if (_current == null) // position == 0
163 _current = _nav.Clone ();
169 internal class SelfIterator : SimpleIterator
171 public SelfIterator (BaseIterator iter) : base (iter) {}
172 public SelfIterator (XPathNavigator nav, NSResolver nsm) : base (nav, nsm) {}
173 protected SelfIterator (SelfIterator other, bool clone) : base (other, true)
177 public override XPathNodeIterator Clone () { return new SelfIterator (this, true); }
178 public override bool MoveNextCore ()
180 if (CurrentPosition == 0)
187 public override XPathNavigator Current {
192 internal class NullIterator : SelfIterator
194 public NullIterator (BaseIterator iter) : base (iter) {}
195 public NullIterator (XPathNavigator nav) : this (nav, null) {}
196 public NullIterator (XPathNavigator nav, NSResolver nsm) : base (nav, nsm) {}
197 private NullIterator (NullIterator other) : base (other, true) {}
198 public override XPathNodeIterator Clone () { return new NullIterator (this); }
199 public override bool MoveNextCore ()
205 internal class ParensIterator : BaseIterator
209 public ParensIterator (BaseIterator iter) : base (iter.NamespaceManager)
213 private ParensIterator (ParensIterator other) : base (other)
215 _iter = (BaseIterator) other._iter.Clone ();
217 public override XPathNodeIterator Clone () { return new ParensIterator (this); }
218 public override bool MoveNextCore ()
220 return _iter.MoveNext ();
223 public override XPathNavigator Current { get { return _iter.Current; }}
225 public override int Count { get { return _iter.Count; } }
228 internal class ParentIterator : SimpleIterator
231 public ParentIterator (BaseIterator iter) : base (iter)
233 canMove = _nav.MoveToParent ();
236 private ParentIterator (ParentIterator other, bool dummy) : base (other, true)
239 canMove = other.canMove;
241 public ParentIterator (XPathNavigator nav, NSResolver nsm) : base (nav, nsm) {}
242 public override XPathNodeIterator Clone () { return new ParentIterator (this, true); }
243 public override bool MoveNextCore ()
252 internal class ChildIterator : SimpleIterator
254 public ChildIterator (BaseIterator iter) : base (iter) {}
255 private ChildIterator (ChildIterator other) : base (other, true) {}
256 public override XPathNodeIterator Clone () { return new ChildIterator (this); }
257 public override bool MoveNextCore ()
259 bool fSuccess = (CurrentPosition == 0) ? _nav.MoveToFirstChild () : _nav.MoveToNext ();
261 Current.MoveTo (_nav);
267 internal class FollowingSiblingIterator : SimpleIterator
269 public FollowingSiblingIterator (BaseIterator iter) : base (iter) {}
270 private FollowingSiblingIterator (FollowingSiblingIterator other) : base (other, true) {}
271 public override XPathNodeIterator Clone () { return new FollowingSiblingIterator (this); }
272 public override bool MoveNextCore ()
274 switch (_nav.NodeType) {
275 case XPathNodeType.Attribute:
276 case XPathNodeType.Namespace:
277 // They have no siblings.
280 if (_nav.MoveToNext ())
282 Current.MoveTo (_nav);
289 internal class PrecedingSiblingIterator : SimpleIterator
293 XPathNavigator startPosition;
295 public PrecedingSiblingIterator (BaseIterator iter) : base (iter)
297 startPosition = iter.Current.Clone ();
299 private PrecedingSiblingIterator (PrecedingSiblingIterator other) : base (other, true)
301 startPosition = other.startPosition;
302 started = other.started;
303 finished = other.finished;
306 public override XPathNodeIterator Clone () { return new PrecedingSiblingIterator (this); }
307 public override bool MoveNextCore ()
313 switch (_nav.NodeType) {
314 case XPathNodeType.Attribute:
315 case XPathNodeType.Namespace:
316 // They have no siblings.
322 if (!_nav.IsSamePosition (startPosition)) {
323 Current.MoveTo (_nav);
327 if (!_nav.MoveToNext ()) {
332 if (_nav.ComparePosition (startPosition) != XmlNodeOrder.Before) {
333 // Note that if _nav contains only 1 node, it won't be Same.
337 Current.MoveTo (_nav);
341 public override bool ReverseAxis {
346 internal class AncestorIterator : SimpleIterator
349 ArrayList navigators;
350 XPathNavigator startPosition;
352 public AncestorIterator (BaseIterator iter) : base (iter)
354 startPosition = iter.Current.Clone ();
357 private AncestorIterator (AncestorIterator other)
360 startPosition = other.startPosition;
361 if (other.navigators != null)
362 navigators = (ArrayList) other.navigators;
363 currentPosition = other.currentPosition;
366 public override XPathNodeIterator Clone ()
368 return new AncestorIterator (this);
371 private void CollectResults ()
373 navigators = new ArrayList ();
375 XPathNavigator ancestors = startPosition.Clone ();
376 if (!ancestors.MoveToParent ())
378 while (ancestors.NodeType != XPathNodeType.Root) {
379 navigators.Add (ancestors.Clone ());
380 ancestors.MoveToParent ();
382 currentPosition = navigators.Count;
385 public override bool MoveNextCore ()
387 if (navigators == null) {
389 if (startPosition.NodeType != XPathNodeType.Root) {
390 // First time it returns Root
392 Current.MoveTo (_nav);
396 if (currentPosition == 0)
398 _nav.MoveTo ((XPathNavigator) navigators [--currentPosition]);
399 Current.MoveTo (_nav);
403 public override bool ReverseAxis {
407 public override int Count {
409 if (navigators == null)
411 return navigators.Count;
416 internal class AncestorOrSelfIterator : SimpleIterator
419 ArrayList navigators;
420 XPathNavigator startPosition;
422 public AncestorOrSelfIterator (BaseIterator iter) : base (iter)
424 startPosition = iter.Current.Clone ();
427 private AncestorOrSelfIterator (AncestorOrSelfIterator other)
430 startPosition = other.startPosition;
431 if (other.navigators != null)
432 navigators = (ArrayList) other.navigators.Clone ();
433 currentPosition = other.currentPosition;
436 public override XPathNodeIterator Clone ()
438 return new AncestorOrSelfIterator (this);
441 private void CollectResults ()
443 navigators = new ArrayList ();
445 XPathNavigator ancestors = startPosition.Clone ();
446 if (!ancestors.MoveToParent ())
448 while (ancestors.NodeType != XPathNodeType.Root) {
449 navigators.Add (ancestors.Clone ());
450 ancestors.MoveToParent ();
452 currentPosition = navigators.Count;
455 public override bool MoveNextCore ()
457 if (navigators == null) {
459 if (startPosition.NodeType != XPathNodeType.Root) {
460 // First time it returns Root
462 Current.MoveTo (_nav);
466 if (currentPosition == -1)
468 if (currentPosition-- == 0) {
469 _nav.MoveTo (startPosition);
470 Current.MoveTo (_nav);
471 return true; // returns self.
473 _nav.MoveTo ((XPathNavigator) navigators [currentPosition]);
474 Current.MoveTo (_nav);
478 public override bool ReverseAxis {
482 public override int Count {
484 if (navigators == null)
486 return navigators.Count + 1;
491 internal class DescendantIterator : SimpleIterator
494 private bool _finished;
496 public DescendantIterator (BaseIterator iter) : base (iter) {}
498 private DescendantIterator (DescendantIterator other) : base (other)
500 _depth = other._depth;
501 _finished = other._finished;
504 public override XPathNodeIterator Clone () { return new DescendantIterator (this); }
506 public override bool MoveNextCore ()
511 if (_nav.MoveToFirstChild ())
514 Current.MoveTo (_nav);
519 if (_nav.MoveToNext ())
521 Current.MoveTo (_nav);
524 if (!_nav.MoveToParent ()) // should NEVER fail!
525 throw new XPathException ("There seems some bugs on the XPathNavigator implementation class: " + _nav.GetType ());
533 internal class DescendantOrSelfIterator : SimpleIterator
536 private bool _finished;
538 public DescendantOrSelfIterator (BaseIterator iter) : base (iter) {}
540 private DescendantOrSelfIterator (DescendantOrSelfIterator other) : base (other, true)
542 _depth = other._depth;
545 public override XPathNodeIterator Clone () { return new DescendantOrSelfIterator (this); }
547 public override bool MoveNextCore ()
552 if (CurrentPosition == 0)
555 Current.MoveTo (_nav);
558 if (_nav.MoveToFirstChild ())
561 Current.MoveTo (_nav);
566 if (_nav.MoveToNext ())
568 Current.MoveTo (_nav);
571 if (!_nav.MoveToParent ()) // should NEVER fail!
572 throw new XPathException ("There seems some bugs on the XPathNavigator implementation class: " + _nav.GetType ());
580 internal class FollowingIterator : SimpleIterator
582 private bool _finished = false;
583 public FollowingIterator (BaseIterator iter) : base (iter) {}
584 private FollowingIterator (FollowingIterator other) : base (other, true) {}
585 public override XPathNodeIterator Clone () { return new FollowingIterator (this); }
586 public override bool MoveNextCore ()
590 bool checkChildren = true;
591 if (CurrentPosition == 0)
593 checkChildren = false;
594 switch (_nav.NodeType) {
595 case XPathNodeType.Attribute:
596 case XPathNodeType.Namespace:
597 _nav.MoveToParent ();
598 checkChildren = true;
601 if (_nav.MoveToNext ())
603 Current.MoveTo (_nav);
606 while (_nav.MoveToParent ()) {
607 if (_nav.MoveToNext ()) {
608 Current.MoveTo (_nav);
618 if (_nav.MoveToFirstChild ())
620 Current.MoveTo (_nav);
625 if (_nav.MoveToNext ())
627 Current.MoveTo (_nav);
631 while (_nav.MoveToParent ());
638 internal class PrecedingIterator : SimpleIterator
642 XPathNavigator startPosition;
644 public PrecedingIterator (BaseIterator iter) : base (iter)
646 startPosition = iter.Current.Clone ();
648 private PrecedingIterator (PrecedingIterator other) : base (other, true)
650 startPosition = other.startPosition;
651 started = other.started;
652 finished = other.finished;
654 public override XPathNodeIterator Clone () { return new PrecedingIterator (this); }
655 public override bool MoveNextCore ()
665 while (!_nav.MoveToFirstChild ()) {
666 while (!_nav.MoveToNext ()) {
667 if (!_nav.MoveToParent ()) { // Should not finish, at least before startPosition.
674 if (_nav.IsDescendant (startPosition))
679 if (_nav.ComparePosition (startPosition) != XmlNodeOrder.Before) {
680 // Note that if _nav contains only 1 node, it won't be Same.
684 Current.MoveTo (_nav);
688 public override bool ReverseAxis {
693 internal class NamespaceIterator : SimpleIterator
695 public NamespaceIterator (BaseIterator iter) : base (iter) {}
696 private NamespaceIterator (NamespaceIterator other) : base (other, true) {}
697 public override XPathNodeIterator Clone () { return new NamespaceIterator (this); }
698 public override bool MoveNextCore ()
700 if (CurrentPosition == 0)
702 if (_nav.MoveToFirstNamespace ())
704 Current.MoveTo (_nav);
708 else if (_nav.MoveToNextNamespace ())
710 Current.MoveTo (_nav);
717 internal class AttributeIterator : SimpleIterator
719 public AttributeIterator (BaseIterator iter) : base (iter) {}
720 private AttributeIterator (AttributeIterator other) : base (other, true) {}
721 public override XPathNodeIterator Clone () { return new AttributeIterator (this); }
722 public override bool MoveNextCore ()
724 if (CurrentPosition == 0)
726 if (_nav.MoveToFirstAttribute ())
728 Current.MoveTo (_nav);
732 else if (_nav.MoveToNextAttribute ())
734 Current.MoveTo (_nav);
741 internal class AxisIterator : BaseIterator
743 private SimpleIterator _iter;
744 private NodeTest _test;
747 XPathNodeType matchType;
749 public AxisIterator (SimpleIterator iter, NodeTest test) : base (iter.NamespaceManager)
753 test.GetInfo (out name, out ns, out matchType, NamespaceManager);
755 // name = Current.NameTable.Add (name);
758 // ns = Current.NameTable.Add (ns);
761 private AxisIterator (AxisIterator other) : base (other)
763 _iter = (SimpleIterator) other._iter.Clone ();
767 matchType = other.matchType;
769 public override XPathNodeIterator Clone () { return new AxisIterator (this); }
771 public override bool MoveNextCore ()
773 while (_iter.MoveNext ())
775 if (_test.Match (NamespaceManager, Current))
782 public override XPathNavigator Current { get { return _iter.Current; }}
784 public override bool ReverseAxis {
785 get { return _iter.ReverseAxis; }
789 internal class SimpleSlashIterator : BaseIterator
791 private NodeSet _expr;
792 private BaseIterator _left, _right;
793 private XPathNavigator _current;
795 public SimpleSlashIterator (BaseIterator left, NodeSet expr)
796 : base (left.NamespaceManager)
802 private SimpleSlashIterator (SimpleSlashIterator other)
806 _left = (BaseIterator) other._left.Clone ();
807 if (other._right != null)
808 _right = (BaseIterator) other._right.Clone ();
811 public override XPathNodeIterator Clone () { return new SimpleSlashIterator (this); }
813 public override bool MoveNextCore ()
815 while (_right == null || !_right.MoveNext ()) {
816 if (!_left.MoveNext ())
818 _right = _expr.EvaluateNodeSet (_left);
820 if (_current == null)
821 _current = _right.Current.Clone ();
823 if (! _current.MoveTo (_right.Current) )
824 _current = _right.Current.Clone ();
828 public override XPathNavigator Current {
829 get { return _current; }
833 internal class SlashIterator : BaseIterator
835 private BaseIterator _iterLeft;
836 private BaseIterator _iterRight;
837 private NodeSet _expr;
839 SortedList _iterList;
841 BaseIterator _nextIterRight;
843 public SlashIterator (BaseIterator iter, NodeSet expr, bool requireSorting) : base (iter.NamespaceManager)
852 private SlashIterator (SlashIterator other) : base (other)
854 _iterLeft = (BaseIterator) other._iterLeft.Clone ();
855 if (other._iterRight != null)
856 _iterRight = (BaseIterator) other._iterRight.Clone ();
858 if (other._iterList != null)
859 _iterList = (SortedList) other._iterList.Clone ();
860 if (other._navStore != null)
861 _navStore = (ArrayList) other._navStore.Clone ();
862 _finished = other._finished;
863 if (other._nextIterRight != null)
864 _nextIterRight = (BaseIterator) other._nextIterRight.Clone ();
866 public override XPathNodeIterator Clone () { return new SlashIterator (this); }
868 public override bool MoveNextCore ()
872 if (_navStore != null) {
873 // Which requires sorting::
874 if (_navStore.Count < CurrentPosition + 1) {
878 while (_navStore.Count > CurrentPosition + 1) {
879 if (((XPathNavigator) _navStore [CurrentPosition + 1]).IsSamePosition (
880 (XPathNavigator) _navStore [CurrentPosition]))
881 _navStore.RemoveAt (CurrentPosition + 1);
888 // Which does not require sorting::
890 if (_iterRight == null) { // First time
891 if (!_iterLeft.MoveNext ())
893 _iterRight = _expr.EvaluateNodeSet (_iterLeft);
894 _iterList = new SortedList (XPathIteratorComparer.Instance);
898 while (!_iterRight.MoveNext ()) {
899 if (_iterList.Count > 0) {
900 int last = _iterList.Count - 1;
901 _iterRight = (BaseIterator) _iterList.GetByIndex (last);
902 _iterList.RemoveAt (last);
904 } else if (_nextIterRight != null) {
905 _iterRight = _nextIterRight;
906 _nextIterRight = null;
908 } else if (!_iterLeft.MoveNext ()) {
913 _iterRight = _expr.EvaluateNodeSet (_iterLeft);
918 if (_nextIterRight == null) {
919 bool noMoreNext = false;
920 while (_nextIterRight == null || !_nextIterRight.MoveNext ()) {
921 if(_iterLeft.MoveNext ())
922 _nextIterRight = _expr.EvaluateNodeSet (_iterLeft);
929 _nextIterRight = null; // FIXME: More efficient code. Maybe making noMoreNext class scope would be better.
931 if (_nextIterRight != null) {
932 switch (_iterRight.Current.ComparePosition (_nextIterRight.Current)) {
933 case XmlNodeOrder.After:
934 _iterList [_iterRight] = _iterRight;
935 _iterRight = _nextIterRight;
936 _nextIterRight = null;
939 case XmlNodeOrder.Same:
940 if (!_nextIterRight.MoveNext ())
941 _nextIterRight = null;
944 int last = _iterList.Count;
945 _iterList [_nextIterRight] = _nextIterRight;
946 if (last != _iterList.Count) {
947 _nextIterRight = (BaseIterator) _iterList.GetByIndex (last);
948 _iterList.RemoveAt (last);
961 private void CollectResults ()
963 _navStore = new ArrayList ();
965 while (_iterRight == null || !_iterRight.MoveNext ()) {
966 if (!_iterLeft.MoveNext ()) {
967 _navStore.Sort (XPathNavigatorComparer.Instance);
970 _iterRight = _expr.EvaluateNodeSet (_iterLeft);
972 XPathNavigator nav = _iterRight.Current;
973 _navStore.Add (nav.Clone ());
977 public override XPathNavigator Current {
979 if (CurrentPosition <= 0) return null;
980 if (_navStore != null) {
981 return (XPathNavigator) _navStore [CurrentPosition - 1];
983 return _iterRight.Current;
988 public override int Count { get { return _navStore == null ? base.Count : _navStore.Count; } }
991 internal class PredicateIterator : BaseIterator
993 private BaseIterator _iter;
994 private Expression _pred;
995 private XPathResultType resType;
996 private bool finished;
998 public PredicateIterator (BaseIterator iter, Expression pred) : base (iter.NamespaceManager)
1002 resType = pred.GetReturnType (iter);
1005 private PredicateIterator (PredicateIterator other) : base (other)
1007 _iter = (BaseIterator) other._iter.Clone ();
1008 _pred = other._pred;
1009 resType = other.resType;
1010 finished = other.finished;
1012 public override XPathNodeIterator Clone () { return new PredicateIterator (this); }
1014 public override bool MoveNextCore ()
1018 while (_iter.MoveNext ())
1021 case XPathResultType.Number:
1022 if (_pred.EvaluateNumber (_iter) != _iter.ComparablePosition)
1026 case XPathResultType.Any: {
1027 object result = _pred.Evaluate (_iter);
1028 if (result is double)
1030 if ((double) result != _iter.ComparablePosition)
1034 else if (!XPathFunctions.ToBoolean (result))
1039 if (!_pred.EvaluateBoolean (_iter))
1048 public override XPathNavigator Current { get { return _iter.Current; }}
1049 public override bool ReverseAxis {
1050 get { return _iter.ReverseAxis; }
1054 internal class ListIterator : BaseIterator
1056 private IList _list;
1058 public ListIterator (BaseIterator iter, IList list) : base (iter.NamespaceManager)
1060 if (!(list is ICloneable))
1061 throw new ArgumentException ("Target enumerator must be cloneable.");
1065 public ListIterator (IList list, NSResolver nsm) : base (nsm)
1067 if (!(list is ICloneable))
1068 throw new ArgumentException ("Target enumerator must be cloneable.");
1072 private ListIterator (ListIterator other) : base (other)
1074 ICloneable listClone = other._list as ICloneable;
1075 _list = (IList) listClone.Clone ();
1077 public override XPathNodeIterator Clone () { return new ListIterator (this); }
1079 public override bool MoveNextCore ()
1081 if (CurrentPosition >= _list.Count)
1085 public override XPathNavigator Current {
1087 if (_list.Count == 0)
1089 return (XPathNavigator) _list [CurrentPosition - 1];
1093 public override int Count { get { return _list.Count; } }
1097 internal class UnionIterator : BaseIterator
1099 private BaseIterator _left, _right;
1100 private bool keepLeft;
1101 private bool keepRight;
1102 XPathNavigator _current;
1104 public UnionIterator (BaseIterator iter, BaseIterator left, BaseIterator right) : base (iter.NamespaceManager)
1110 private UnionIterator (UnionIterator other) : base (other)
1112 _left = (BaseIterator) other._left.Clone ();
1113 _right = (BaseIterator) other._right.Clone ();
1114 keepLeft = other.keepLeft;
1115 keepRight = other.keepRight;
1116 if (other._current != null)
1117 _current = other._current.Clone ();
1119 public override XPathNodeIterator Clone () { return new UnionIterator (this); }
1121 public override bool MoveNextCore ()
1124 keepLeft = _left.MoveNext ();
1126 keepRight = _right.MoveNext ();
1128 if (!keepLeft && !keepRight)
1135 } else if (!keepLeft) {
1137 SetCurrent (_right);
1141 switch (_left.Current.ComparePosition (_right.Current)) {
1142 case XmlNodeOrder.Same:
1143 // consume both. i.e. don't output duplicate result.
1144 keepLeft = keepRight = false;
1145 SetCurrent (_right);
1147 case XmlNodeOrder.Before:
1148 case XmlNodeOrder.Unknown: // Maybe happen because of "document(a) | document(b)"
1152 case XmlNodeOrder.After:
1154 SetCurrent (_right);
1157 throw new InvalidOperationException ("Should not happen.");
1161 private void SetCurrent (XPathNodeIterator iter)
1163 if (_current == null)
1164 _current = iter.Current.Clone ();
1166 if (! _current.MoveTo (iter.Current) )
1167 _current = iter.Current.Clone ();
1170 public override XPathNavigator Current
1172 get { return _current; }
1176 internal class OrderedIterator : BaseIterator
1182 public OrderedIterator (BaseIterator iter)
1183 : base (iter.NamespaceManager)
1185 // if (iter.Ordered)
1189 list = new ArrayList ();
1190 while (iter.MoveNext ())
1191 list.Add (iter.Current);
1192 list.Sort (XPathNavigatorComparer.Instance);
1196 private OrderedIterator (OrderedIterator other, bool dummy)
1199 if (other.iter != null)
1200 iter = (BaseIterator) other.iter.Clone ();
1202 index = other.index;
1205 public override XPathNodeIterator Clone ()
1207 return new OrderedIterator (this);
1210 public override bool MoveNextCore ()
1213 return iter.MoveNext ();
1214 else if (index++ < list.Count)
1220 public override XPathNavigator Current {
1221 get { return iter != null ? iter.Current : index < 0 ? null : (XPathNavigator) list [index]; }