Exemple #1
0
		internal XQueryContextManager (XQueryStaticContext ctx, XPathItem input, XmlWriter writer, XmlResolver resolver, XmlArgumentList args)
		{
			this.input = input;
			this.staticContext = ctx;
			this.args = args;
			currentWriter = writer;
			this.extDocResolver = resolver;

			namespaceManager = new XmlNamespaceManager (ctx.NameTable);
			foreach (DictionaryEntry de in ctx.NSResolver.GetNamespacesInScope (XmlNamespaceScope.ExcludeXml))
				namespaceManager.AddNamespace (de.Key.ToString (), de.Value.ToString ());
			namespaceManager.PushScope ();

			currentContext = new XQueryContext (this, null, new Hashtable ());
			if (input != null) {
				currentSequence = new SingleItemIterator (input, currentContext);
				currentSequence.MoveNext ();
			}
			currentContext = new XQueryContext (this, currentSequence, new Hashtable ());
		}
		private static int FnMaxInteger (XPathSequence e)
		{
			int ret = int.MinValue;
			do {
				ret = System.Math.Max (e.Current.ValueAsInt32, ret);
			} while (e.MoveNext ());
			return ret;
		}
		private static decimal FnMaxDecimal (XPathSequence e)
		{
			decimal ret = decimal.MinValue;
			do {
				ret = System.Math.Max (e.Current.ValueAsDecimal, ret);
			} while (e.MoveNext ());
			return ret;
		}
		public static bool FnDeepEqualImpl (XPathSequence p1, XPathSequence p2, CultureInfo collation)
		{
			// FIXME: use collation
			while (p1.MoveNext ()) {
				if (!p2.MoveNext ())
					return false;
				if (!FnDeepEqualItem (p1.Current, p2.Current, collation))
					return false;
			}
			if (p2.MoveNext ())
				return false;
			return true;
		}
		public static XPathItem FnExactlyOne (XPathSequence e)
		{
			if (!e.MoveNext ())
				throw new XmlQueryException ("exactly-one() function detected that the argument sequence contains no items.");
			XPathItem item = e.Current;
			if (e.MoveNext ())
				throw new XmlQueryException ("exactly-one() function detected that the argument sequence contains two or more items.");
			return item;
		}
		public static XPathItem FnZeroOrOne (XPathSequence e)
		{
			if (!e.MoveNext ())
				return null;
			XPathItem item = e.Current;
			if (e.MoveNext ())
				throw new XmlQueryException ("zero-or-one() function detected that the argument sequence contains two or more items.");
			return item;
		}
Exemple #7
0
		// returns null if sequence was empty
		private XPathNavigator ExamineOneNode (XPathSequence seq)
		{
			if (!seq.MoveNext ())
				return null;
			XPathNavigator nav = seq.Current as XPathNavigator;
			if (nav == null || seq.MoveNext ())
				throw new XmlQueryException ("Operand of node comparison expression must be evaluated as a sequence that contains exactly one node.");
			return nav;
		}
		private static object FnMinImpl (XPathSequence e, CultureInfo collation)
		{
			if (!e.MoveNext ())
				return null;
			switch (e.Current.XmlType.TypeCode) {
			case XmlTypeCode.DayTimeDuration:
				return FnMinDayTimeDuration (e);
			case XmlTypeCode.YearMonthDuration:
				return FnMinYearMonthDuration (e);
			case XmlTypeCode.Decimal:
				return FnMinDecimal (e);
			case XmlTypeCode.Integer:
				return FnMinInteger (e);
			case XmlTypeCode.Float:
				return FnMinFloat (e);
			case XmlTypeCode.UntypedAtomic:
			case XmlTypeCode.Double:
				return FnMinDouble (e);
			}
			throw new XmlQueryException ("avg() function detected that the sequence contains an item whose type is neither of dayTimeDuration, yearMonthDuration, decimal, integer, float, double, nor untypedAtomic.");
		}
Exemple #9
0
		public object ToRuntimeType (XPathSequence seq)
		{
			// FIXME: handle ZeroOrMore|OneOrMore
			switch (occurence) {
			case Occurence.One:
			case Occurence.Optional:
				if (!seq.MoveNext ())
					return null;
				XPathItem item = seq.Current;
				// FIXME: should check and reject two or 
				// more items??
				return item.TypedValue;
			}
			ArrayList al = new ArrayList ();
			while (seq.MoveNext ())
				al.Add (seq.Current.TypedValue);
			return al.ToArray (InternalPool.RuntimeTypeFromXmlTypeCode (schemaType.TypeCode));
//			return seq;
		}
Exemple #10
0
		protected override bool MoveNextCore ()
		{
			if (finished)
				return false;
			if (step.RequireSorting) {
				// Mainly '//' ('/descendant-or-self::node()/')
				if (nodeStore == null) {
					CollectResults ();
					if (nodeStore.Count == 0) {
						finished = true;
						return false;
					} else
						// Initially it must not go to
						// the while loop below
						// (.Position -1 is -1).
						return true;
				}
				if (nodeStore.Count == Position) {
					finished = true;
					return false;
				}
				while (nodeStore.Count > Position) {
					if (((XPathNavigator) nodeStore [Position]).ComparePosition (
						(XPathNavigator) nodeStore [Position - 1]) == XmlNodeOrder.Same)
						nodeStore.RemoveAt (Position);
					else
						break;
				}

				return true;
			} else { // Sorting not required
				if (right == null) { // First time
					if (!left.MoveNext ())
						return false;
					right = step.Next.Evaluate (left);
					storedIterators = new SortedList (XPathSequenceComparer.Instance);
				}

				while (true) {
					while (!right.MoveNext ()) {
						if (storedIterators.Count > 0) {
							int last = storedIterators.Count - 1;
							XPathSequence tmpIter = (XPathSequence) storedIterators.GetByIndex (last);
							storedIterators.RemoveAt (last);
							switch (((XPathNavigator) tmpIter.Current).ComparePosition ((XPathNavigator) right.Current)) {
							case XmlNodeOrder.Same:
							case XmlNodeOrder.Before:
								right = tmpIter;
								continue;
							default:
								right = tmpIter;
								break;
							}
							break;
						} else if (nextRight != null) {
							right = nextRight;
							nextRight = null;
							break;
						} else if (!left.MoveNext ()) {
							finished = true;
							return false;
						}
						else
							right = step.Next.Evaluate (left);
					}
					bool loop = true;
					while (loop) {
						loop = false;
						if (nextRight == null) {
							bool noMoreNext = false;
							while (nextRight == null || !nextRight.MoveNext ()) {
								if(left.MoveNext ())
									nextRight = step.Next.Evaluate (left);
								else {
									noMoreNext = true;
									break;
								}
							}
							if (noMoreNext)
								nextRight = null; // FIXME: More efficient code. Maybe making noMoreNext class scope would be better.
						}
						if (nextRight != null) {
							switch (((XPathNavigator) right.Current).ComparePosition ((XPathNavigator) nextRight.Current)) {
							case XmlNodeOrder.After:
								storedIterators.Add (storedIterators.Count, right);
								right = nextRight;
								nextRight = null;
								loop = true;
								break;
							case XmlNodeOrder.Same:
								if (!nextRight.MoveNext ())
									nextRight = null;

								else {
									int last = storedIterators.Count;
									if (last > 0) {
										storedIterators.Add (last, nextRight);
										nextRight = (XPathSequence) storedIterators.GetByIndex (last);
										storedIterators.RemoveAt (last);
									}
								}

								loop = true;
								break;
							}
						}
					}
					return true;
				}
			}
		}
Exemple #11
0
		private IEnumerator EvaluateRemainingSingleItem (int flcPosition, int singlePosition)
		{
			if (singlePosition < expr.ForLetClauses [flcPosition].Count) {
				ForLetSingleBody sb = expr.ForLetClauses [flcPosition] [singlePosition];
				ForSingleBody fsb = sb as ForSingleBody;
				if (fsb != null) {
					XPathSequence backup = contextSequence;
					contextSequence = fsb.Expression.Evaluate (Context.CurrentSequence);
					Context.ContextManager.PushCurrentSequence (contextSequence);
					while (contextSequence.MoveNext ()) {
						XPathItem forItem = (XPathItem) contextSequence.Current;
						Context.PushVariable (fsb.PositionalVar, contextSequence.Position);
						Context.PushVariable (sb.VarName, forItem);
						// recurse here (including following bindings)
						IEnumerator items = EvaluateRemainingSingleItem (flcPosition, singlePosition + 1);
						while (items.MoveNext ())
							yield return (XPathItem) items.Current;
						Context.PopVariable ();
						Context.PopVariable ();
					}
					Context.ContextManager.PopCurrentSequence ();
					contextSequence = backup;
				} else {
					Context.PushVariable (sb.VarName, sb.Expression.Evaluate (contextSequence));
					// recurse here (including following bindings)
					IEnumerator items = EvaluateRemainingSingleItem (flcPosition, singlePosition + 1);
					while (items.MoveNext ())
						yield return (XPathItem) items.Current;
					Context.PopVariable ();
				}
			} else {
				// evaluate next binding
				IEnumerator items = EvaluateRemainingForLet (flcPosition + 1);
				while (items.MoveNext ())
					yield return (XPathItem) items.Current;
			}
		}
Exemple #12
0
		protected override bool MoveNextCore ()
		{
			if (iter != null && iter.MoveNext ())
				return true;
			while (currentExprIndex < expr.Count) {
				iter = expr [currentExprIndex++].Evaluate (contextSequence);
				if (iter.MoveNext ())
					return true;
			}
			return false;
		}
Exemple #13
0
		// FIXME: What if iter contains list value?
		public static XPathAtomicValue Atomize (XPathSequence iter)
		{
			if (!iter.MoveNext ())
				return null;
			XPathNavigator nav = iter.Current as XPathNavigator;
			if (nav != null) {
				// FIXME: is it really always untypedAtomic?
				// It might be complex content.
				XmlSchemaType type = nav.SchemaInfo == null ? InternalPool.XdtUntypedAtomic : nav.SchemaInfo.SchemaType;
				return new XPathAtomicValue (nav.TypedValue, type);
			}
			else
				return (XPathAtomicValue) iter.Current;
		}
Exemple #14
0
		public override XPathSequence Evaluate (XPathSequence iter)
		{
			XQueryContext ctx = iter.Context;

			if (iter.Position == 0) {
				iter = iter.Clone ();
				if (!iter.MoveNext ())
					return new XPathEmptySequence (iter.Context);
			}

			XPathNavigator nav = iter.Current as XPathNavigator;
			if (nav == null)
				throw new XmlQueryException ("Node set is expected.");

			NodeIterator argIter = null;

			switch (Axis.AxisType) {
			case XPathAxisType.Child:
				argIter = new ChildIterator (nav, ctx); break;
			case XPathAxisType.Descendant:
				argIter = new DescendantIterator (nav, ctx); break;
			case XPathAxisType.Attribute:
				argIter = new AttributeIterator (nav, ctx); break;
			case XPathAxisType.Self:
				argIter = new SelfIterator (nav, ctx); break;
			case XPathAxisType.DescendantOrSelf:
				argIter = new DescendantOrSelfIterator (nav, ctx); break;
			case XPathAxisType.FollowingSibling:
				argIter = new FollowingSiblingIterator (nav, ctx); break;
			case XPathAxisType.Following:
				argIter = new FollowingIterator (nav, ctx); break;
			case XPathAxisType.Parent:
				argIter = new ParentIterator (nav, ctx); break;
			case XPathAxisType.Ancestor:
				argIter = new AncestorIterator (nav, ctx); break;
			case XPathAxisType.PrecedingSibling:
				argIter = new PrecedingSiblingIterator (nav, ctx); break;
			case XPathAxisType.Preceding:
				argIter = new PrecedingIterator (nav, ctx); break;
			case XPathAxisType.AncestorOrSelf:
				argIter = new AncestorOrSelfIterator (nav, ctx); break;
			case XPathAxisType.Namespace: // only applicable under XPath 2.0: not XQuery 1.0
				argIter = new NamespaceIterator (nav, ctx); break;
			}
			return new AxisIterator (argIter, this);
		}
		private static float FnMaxFloat (XPathSequence e)
		{
			float ret = float.MinValue;
			do {
				ret = System.Math.Max (e.Current.ValueAsSingle, ret);
			} while (e.MoveNext ());
			return ret;
		}
		public static bool FnExists (XPathSequence e)
		{
			if (e is XPathEmptySequence)
				return false;
			return e.MoveNext ();
		}
		private static double FnMaxDouble (XPathSequence e)
		{
			double ret = double.MinValue;
			do {
				ret = System.Math.Max (e.Current.ValueAsDouble, ret);
			} while (e.MoveNext ());
			return ret;
		}
		public static XPathSequence FnReverse (XPathSequence arg)
		{
			ArrayList al = new ArrayList ();
			while (arg.MoveNext ())
				al.Add (arg.Current);
			al.Reverse ();
			return new ListIterator (arg.Context, al);
		}
		private static TimeSpan FnMinYearMonthDuration (XPathSequence e)
		{
			// FIXME: reject dTD (but is it possible...?)
			TimeSpan ret = TimeSpan.Zero;
			do {
				TimeSpan ts = (TimeSpan) e.Current.TypedValue;
				if (ts > ret)
					ret = ts;
			} while (e.MoveNext ());
			return ret;
		}
Exemple #20
0
		// returns null if sequence was empty
		private XPathItem ExamineOneItem (XPathSequence seq)
		{
			if (!seq.MoveNext ())
				return null;
			XPathItem item = seq.Current;
			if (seq.MoveNext ())
				throw new XmlQueryException ("Operand of value comparison expression must be evaluated as a sequence that contains exactly one item.");
			return item;
		}