using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
-
-#if NET_2_0
using NSResolver = System.Xml.IXmlNamespaceResolver;
-#else
-using NSResolver = System.Xml.XmlNamespaceManager;
-#endif
namespace System.Xml.XPath
{
public abstract bool MoveNextCore ();
+ internal XPathNavigator PeekNext ()
+ {
+ XPathNodeIterator i = Clone ();
+ return i.MoveNext () ? i.Current : null;
+ }
+
public override string ToString ()
{
if (Current != null)
get {
if (CurrentPosition == 0)
return null;
- if (_current == null)
- _current = _nav.Clone ();
- _current.MoveTo (_nav);
+ _current = _nav;
return _current;
}
}
public override int CurrentPosition {
get { return 1; }
}
+
+ public override XPathNavigator Current {
+ get { return _nav; }
+ }
}
internal class ParensIterator : BaseIterator
}
}
- internal class ChildIterator : SimpleIterator
+ internal class ChildIterator : BaseIterator
{
- public ChildIterator (BaseIterator iter) : base (iter) {}
- private ChildIterator (ChildIterator other) : base (other, true) {}
+ XPathNavigator _nav;
+
+ public ChildIterator (BaseIterator iter) : base (iter.NamespaceManager)
+ {
+ _nav = iter.CurrentPosition == 0 ? iter.PeekNext () : iter.Current;
+ if (_nav != null && _nav.HasChildren)
+ _nav = _nav.Clone ();
+ else
+ _nav = null;
+ }
+ private ChildIterator (ChildIterator other) : base (other)
+ {
+ _nav = other._nav == null ? null : other._nav.Clone ();
+ }
+
public override XPathNodeIterator Clone () { return new ChildIterator (this); }
+
public override bool MoveNextCore ()
{
- bool fSuccess = (CurrentPosition == 0) ? _nav.MoveToFirstChild () : _nav.MoveToNext ();
-// if (fSuccess) {
-// Current.MoveTo (_nav);
-// }
- return fSuccess;
+ if (_nav == null)
+ return false;
+
+ return (CurrentPosition == 0) ? _nav.MoveToFirstChild () : _nav.MoveToNext ();
}
public override XPathNavigator Current {
get {
- if (CurrentPosition > 0)
- base.Current.MoveTo (_nav);
- return base.Current;
+ if (CurrentPosition == 0)
+ return null;
+ return _nav;
}
}
}
navigators = new ArrayList ();
XPathNavigator ancestors = startPosition.Clone ();
- if (!ancestors.MoveToParent ())
- return;
- while (ancestors.NodeType != XPathNodeType.Root) {
+ while (ancestors.NodeType != XPathNodeType.Root && ancestors.MoveToParent ())
navigators.Add (ancestors.Clone ());
- ancestors.MoveToParent ();
- }
currentPosition = navigators.Count;
}
public override bool MoveNextCore ()
{
- if (navigators == null) {
+ if (navigators == null)
CollectResults ();
- if (startPosition.NodeType != XPathNodeType.Root) {
- // First time it returns Root
- _nav.MoveToRoot ();
-// Current.MoveTo (_nav);
- return true;
- }
- }
if (currentPosition == -1)
return false;
if (currentPosition-- == 0) {
public DescendantIterator (BaseIterator iter) : base (iter) {}
- private DescendantIterator (DescendantIterator other) : base (other)
+ private DescendantIterator (DescendantIterator other) : base (other, true)
{
_depth = other._depth;
_finished = other._finished;
internal class AxisIterator : BaseIterator
{
- private SimpleIterator _iter;
+ private BaseIterator _iter;
private NodeTest _test;
//string name, ns;
//XPathNodeType matchType;
- public AxisIterator (SimpleIterator iter, NodeTest test) : base (iter.NamespaceManager)
+ public AxisIterator (BaseIterator iter, NodeTest test) : base (iter.NamespaceManager)
{
_iter = iter;
_test = test;
private AxisIterator (AxisIterator other) : base (other)
{
- _iter = (SimpleIterator) other._iter.Clone ();
+ _iter = (BaseIterator) other._iter.Clone ();
_test = other._test;
//name = other.name;
//ns = other.ns;
}
}
+ internal class SortedIterator : BaseIterator
+ {
+ ArrayList list;
+
+ public SortedIterator (BaseIterator iter) : base (iter.NamespaceManager)
+ {
+ list = new ArrayList ();
+ while (iter.MoveNext ())
+ list.Add (iter.Current.Clone ());
+
+ // sort
+ if (list.Count == 0)
+ return;
+ XPathNavigator prev = (XPathNavigator) list [0];
+ list.Sort (XPathNavigatorComparer.Instance);
+ for (int i = 1; i < list.Count; i++) {
+ XPathNavigator n = (XPathNavigator) list [i];
+ if (prev.IsSamePosition (n)) {
+ list.RemoveAt (i);
+ i--;
+ }
+ else
+ prev = n;
+ }
+ }
+
+ public SortedIterator (SortedIterator other) : base (other)
+ {
+ this.list = other.list;
+ SetPosition (other.CurrentPosition);
+ }
+
+ public override XPathNodeIterator Clone () { return new SortedIterator (this); }
+
+ public override bool MoveNextCore ()
+ {
+ return CurrentPosition < list.Count;
+ }
+
+ public override XPathNavigator Current {
+ get { return CurrentPosition == 0 ? null : (XPathNavigator) list [CurrentPosition - 1]; }
+ }
+
+ public override int Count {
+ get { return list.Count; }
+ }
+ }
+
+ // NOTE: it is *not* sorted. Do not directly use it without checking sorting requirement.
internal class SlashIterator : BaseIterator
{
private BaseIterator _iterLeft;
private BaseIterator _iterRight;
private NodeSet _expr;
- ArrayList _navStore;
SortedList _iterList;
bool _finished;
BaseIterator _nextIterRight;
- public SlashIterator (BaseIterator iter, NodeSet expr, bool requireSorting) : base (iter.NamespaceManager)
+ public SlashIterator (BaseIterator iter, NodeSet expr) : base (iter.NamespaceManager)
{
_iterLeft = iter;
_expr = expr;
-
- if (requireSorting)
- CollectResults ();
}
private SlashIterator (SlashIterator other) : base (other)
_expr = other._expr;
if (other._iterList != null)
_iterList = (SortedList) other._iterList.Clone ();
- if (other._navStore != null)
- _navStore = (ArrayList) other._navStore.Clone ();
_finished = other._finished;
if (other._nextIterRight != null)
_nextIterRight = (BaseIterator) other._nextIterRight.Clone ();
{
if (_finished)
return false;
- if (_navStore != null) {
- // Which requires sorting::
- if (_navStore.Count < CurrentPosition + 1) {
- _finished = true;
- return false;
- }
- while (_navStore.Count > CurrentPosition + 1) {
- if (((XPathNavigator) _navStore [CurrentPosition + 1]).IsSamePosition (
- (XPathNavigator) _navStore [CurrentPosition]))
- _navStore.RemoveAt (CurrentPosition + 1);
- else
- break;
- }
- return true;
- }
- // Which does not require sorting::
-
if (_iterRight == null) { // First time
if (!_iterLeft.MoveNext ())
return false;
}
}
- private void CollectResults ()
- {
- _navStore = new ArrayList ();
- while (true) {
- while (_iterRight == null || !_iterRight.MoveNext ()) {
- if (!_iterLeft.MoveNext ()) {
- _navStore.Sort (XPathNavigatorComparer.Instance);
- return;
- }
- _iterRight = _expr.EvaluateNodeSet (_iterLeft);
- }
- XPathNavigator nav = _iterRight.Current;
- _navStore.Add (nav.Clone ());
- }
- }
-
public override XPathNavigator Current {
get {
- if (CurrentPosition <= 0) return null;
- if (_navStore != null) {
- return (XPathNavigator) _navStore [CurrentPosition - 1];
- } else {
- return _iterRight.Current;
- }
+ return (CurrentPosition == 0) ? null : _iterRight.Current;
}
}
-
- public override int Count { get { return _navStore == null ? base.Count : _navStore.Count; } }
}
internal class PredicateIterator : BaseIterator