+2004-08-31 Atsushi Enomoto <atsushi@ximian.com>
+
+ * XPath2Expression.cs,
+ XPathSequence.cs :
+ Implemented GroupExpr.Evaluate() [union/intersect/except].
+ Fixed incorrect iterator input for DescendantExpr.Evaluate().
+ MinusExpr is (already) implemented not to be evaluated.
+ * XQueryExpression.cs :
+ PI name and nameExpr could be implemented.
+ * XQueryFunction.cs :
+ UserFunctionCallExpr.Invoke() should not be invoked.
+ * XQueryFunctionCliImpl.cs :
+ Implemented count(), doc(). Halfly implemented trace().
+ * XmlQueryException.cs : Serializable.
+
2004-08-31 Atsushi Enomoto <atsushi@ximian.com>
* XPath2Expression.cs :
public override XPathSequence Evaluate (XPathSequence iter)
{
- throw new NotImplementedException ();
+ throw new SystemException ("XQuery internal error: should not happen.");
}
#endregion
}
// only applicable against node-sets
public override XPathSequence Evaluate (XPathSequence iter)
{
- XPathSequence lvalue = Left.EvaluateOrdered (iter);
- XPathSequence rvalue = Right.EvaluateOrdered (iter);
-
- /*
- TBD (yield earlier node, skipping one of the same nodes)
- - or -
- TBD (yield earlier node, skipping non-intersection nodes)
- - or -
- TBD (yield earlier node, skipping both of the same nodes)
- */
- throw new NotImplementedException ();
+ return new GroupIterator (iter, this);
}
#endregion
}
if (!seq.MoveNext ())
return new XPathEmptySequence (iter.Context);
return new PathStepIterator (
- new DescendantOrSelfIterator (iter.Current as XPathNavigator, iter.Context), this);
+ new DescendantOrSelfIterator (seq.Current as XPathNavigator, seq.Context), this);
}
#endregion
}
}
}
+ internal class GroupIterator : XPathSequence
+ {
+ GroupExpr expr;
+ XPathSequence lseq;
+ XPathSequence rseq;
+ bool started;
+ bool left;
+ bool leftFinished;
+ bool rightFinished;
+
+ public GroupIterator (XPathSequence iter, GroupExpr expr)
+ : base (iter.Context)
+ {
+ this.expr = expr;
+ left = true;
+ lseq = expr.Left.EvaluateOrdered (iter);
+ rseq = expr.Right.EvaluateOrdered (iter);
+ }
+
+ private GroupIterator (GroupIterator other)
+ : base (other)
+ {
+ this.expr = other.expr;
+ this.started = other.started;
+ this.left = other.left;
+ this.leftFinished = other.leftFinished;
+ this.rightFinished = other.rightFinished;
+ this.lseq = other.lseq.Clone ();
+ this.rseq = other.rseq.Clone ();
+ }
+
+ public override XPathSequence Clone ()
+ {
+ return new GroupIterator (this);
+ }
+
+ protected override bool MoveNextCore ()
+ {
+ if (leftFinished && rightFinished)
+ return false;
+ bool proceeded = false;
+ if (started) {
+ if (left) {
+ if (!leftFinished && lseq.MoveNext ())
+ proceeded = true;
+ else
+ leftFinished = true;
+ } else {
+ if (rightFinished && rseq.MoveNext ())
+ proceeded = true;
+ else
+ rightFinished = true;
+ }
+ } else {
+ started = true;
+ if (!lseq.MoveNext ()) {
+ leftFinished = true;
+ if (!rseq.MoveNext ()) {
+ rightFinished = true;
+ return false;
+ }
+ left = false;
+ return true;
+ }
+ proceeded = true;
+ if (!rseq.MoveNext ()) {
+ rightFinished = true;
+ return true;
+ }
+ }
+ if (!proceeded) {
+ if (expr.AggregationType == AggregationType.Intersect)
+ return false;
+ left = !leftFinished;
+ return !leftFinished || !rightFinished;
+ }
+
+ XPathNavigator lnav = lseq.Current as XPathNavigator;
+ XPathNavigator rnav = rseq.Current as XPathNavigator;
+ if (lnav == null || rnav == null)
+ throw new XmlQueryException ("XP0006: Evaluation against union, intersect, except expressions must result in nodes.");
+ XmlNodeOrder order = lnav.ComparePosition (rnav);
+ switch (order) {
+ case XmlNodeOrder.Same:
+ switch (expr.AggregationType) {
+ case AggregationType.Union:
+ left = false;
+ if (!lseq.MoveNext ())
+ leftFinished = true;
+ return true;
+ case AggregationType.Intersect:
+ return true;
+ case AggregationType.Except:
+ default:
+ return MoveNext ();
+ }
+ case XmlNodeOrder.Before:
+ left = true;
+ if (expr.AggregationType == AggregationType.Intersect)
+ return MoveNext ();
+ return true;
+ default: // After, Unknown
+ left = false;
+ if (expr.AggregationType == AggregationType.Intersect)
+ return MoveNext ();
+ return true;
+ }
+ }
+
+ public override XPathItem CurrentCore {
+ get { return left ? lseq.Current : rseq.Current; }
+ }
+ }
+
internal class AtomizingIterator : XPathSequence
{
XPathSequence iter;
}
public string Name {
- get { throw new NotImplementedException (); }
+ get { return name; }
}
+
public ExprSequence NameExpr {
- get { throw new NotImplementedException (); }
+ get { return nameExpr; }
}
// FIXME: can be optimized by checking all items in Expr
public override object Invoke (XQueryContext context, object [] args)
{
- throw new NotImplementedException ("Not supported");
+ throw new SystemException ("XQuery internal error: should not happen.");
}
public override XPathSequence Evaluate (XPathSequence iter, ExprSequence args)
using System;
using System.Collections;
using System.Globalization;
+using System.IO;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Query;
// Trace
[MonoTODO]
- public static object FnTrace (object arg)
+ public static object FnTrace (XQueryContext ctx, object value, string label)
{
- throw new NotImplementedException ();
+ if (value == null)
+ return new XPathEmptySequence (ctx);
+ XPathSequence seq = value as XPathSequence;
+ if (seq == null) {
+ IEnumerable list = value as IEnumerable;
+ if (list != null)
+ seq = new EnumeratorIterator (ctx, list);
+ else {
+ XPathAtomicValue av = value as XPathAtomicValue;
+ if (av == null)
+ av = new XPathAtomicValue (value,
+ XmlSchemaType.GetBuiltInType (
+ XPathAtomicValue.XmlTypeCodeFromRuntimeType (
+ value.GetType (), true)));
+ seq = new SingleItemIterator (av, ctx);
+ }
+ }
+ return new TracingIterator (seq, label);
}
// Numeric Operation
throw new NotImplementedException ();
}
- [MonoTODO]
- public static object FnCount (IEnumerable e)
+ public static int FnCount (IEnumerable e)
{
- throw new NotImplementedException ();
+ if (e == null)
+ return 0;
+ XPathSequence seq = e as XPathSequence;
+ if (seq != null)
+ return seq.Count;
+ ICollection col = e as ICollection;
+ if (col != null)
+ return col.Count;
+ int count = 0;
+ IEnumerator en = e.GetEnumerator ();
+ while (en.MoveNext ())
+ count++;
+ return count;
}
[MonoTODO]
throw new NotImplementedException ();
}
- [MonoTODO]
- public static object FnDoc (XQueryContext ctx, string uri)
+ public static XPathNavigator FnDoc (XQueryContext ctx, string uri)
{
- throw new NotImplementedException ();
+ XmlResolver res = ctx.ContextManager.ExtDocResolver;
+ string baseUriString = ctx.StaticContext.BaseUri;
+ Uri baseUri = null;
+ if (baseUriString != null && baseUriString != String.Empty)
+ baseUri = new Uri (baseUriString);
+ Uri relUri = res.ResolveUri (baseUri, uri);
+ Stream s = res.GetEntity (relUri, null, typeof (Stream)) as Stream;
+ try {
+ XPathDocument doc = new XPathDocument (new XmlValidatingReader (new XmlTextReader (s)), XmlSpace.Preserve);
+ return doc.CreateNavigator ();
+ } finally {
+ s.Close ();
+ }
}
public static IEnumerable FnCollection (XQueryContext ctx, string name)
\r
namespace System.Xml.Query\r
{\r
+ [Serializable]\r
public class XmlQueryException : SystemException\r
{\r
#region Constructors\r