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; }
// 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."); }
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; }
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; } } }
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; } }
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; }
// 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; }
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; }
// 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; }