Przeglądaj źródła

2004-10-04 Atsushi Enomoto <[email protected]>

	* XQueryParser.jay, XPath2Expression.cs, XPathSequence.cs :
	  two or more Filter expressions could be simply constructed as
	  nested FilterExpr objects.

svn path=/trunk/mcs/; revision=34691
Atsushi Eno 21 lat temu
rodzic
commit
375e5aa0c7

+ 6 - 0
mcs/class/System.XML/System.Xml.Query/ChangeLog

@@ -1,3 +1,9 @@
+2004-10-04  Atsushi Enomoto <[email protected]>
+
+	* XQueryParser.jay, XPath2Expression.cs, XPathSequence.cs :
+	  two or more Filter expressions could be simply constructed as
+	  nested FilterExpr objects.
+
 2004-09-22  Atsushi Enomoto <[email protected]>
 
 	* SequenceType.cs : return TypedValue instead of null in case of

+ 11 - 11
mcs/class/System.XML/System.Xml.Query/XPath2Expression.cs

@@ -137,7 +137,7 @@ namespace Mono.Xml.XPath2
 				XPathNavigator nav = item as XPathNavigator;
 				if (w.WriteState != WriteState.Start && nav.NodeType == XPathNodeType.Root)
 					throw new XmlQueryException ("Current output can not accept root node.");
-				nav.WriteSubtree (w);
+				w.WriteNode (nav, false);
 			} else
 				w.WriteString (item.Value);
 		}
@@ -1842,38 +1842,36 @@ namespace Mono.Xml.XPath2
 
 	internal class FilterStepExpr : PathExpr
 	{
-		public FilterStepExpr (ExprSingle expr, PredicateList predicates)
+		public FilterStepExpr (ExprSingle expr, ExprSequence predicate)
 		{
 			this.expr = expr;
-			this.predicates = predicates;
+			this.predicate = predicate;
 		}
 
 		ExprSingle expr;
-		PredicateList predicates;
+		ExprSequence predicate;
 
 		public ExprSingle Expr {
 			get { return expr; }
 			set { expr = value; }
 		}
 
-		public PredicateList Predicates {
-			get { return predicates; }
+		public ExprSequence Predicate {
+			get { return predicate; }
 		}
 
 		internal override void CheckReference (XQueryASTCompiler compiler)
 		{
 			expr.CheckReference (compiler);
-			foreach (ExprSequence seq in predicates)
-				seq.CheckReference (compiler);
+			predicate.CheckReference (compiler);
 		}
 
 #region CompileAndEvaluate
 		internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
 		{
 			Expr = Expr.Compile (compiler);
-			foreach (ExprSequence seq in Predicates)
-				for (int i = 0; i < seq.Count; i++)
-					seq [i] = seq [i].Compile (compiler);
+			for (int i = 0; i < predicate.Count; i++)
+				predicate [i] = predicate [i].Compile (compiler);
 			return this;
 		}
 
@@ -1888,6 +1886,7 @@ namespace Mono.Xml.XPath2
 #endregion
 	}
 
+/*
 	// predicates == exprsequence list == list of list of exprsingle
 	internal class PredicateList : CollectionBase
 	{
@@ -1905,6 +1904,7 @@ namespace Mono.Xml.XPath2
 			get { return (ExprSequence) List [i]; }
 		}
 	}
+*/
 
 	internal class XPath2NodeTest
 	{

+ 19 - 13
mcs/class/System.XML/System.Xml.Query/XPathSequence.cs

@@ -479,13 +479,13 @@ namespace Mono.Xml.XPath2
 	internal class FilteredIterator : XPathSequence
 	{
 		XPathSequence left;
-		PredicateList filter;
+		ExprSequence filter;
 
 		public FilteredIterator (XPathSequence iter, FilterStepExpr source)
 			: base (iter.Context)
 		{
 			left = source.Expr.Evaluate (iter);
-			filter = source.Predicates;
+			filter = source.Predicate;
 		}
 
 		private FilteredIterator (FilteredIterator other)
@@ -502,25 +502,31 @@ namespace Mono.Xml.XPath2
 
 		protected override bool MoveNextCore ()
 		{
+			// FIXME: as for numeric predicates, it is MUCH faster
+			// when it skips apparent non-candidates, with possible
+			// method implementation "XPathSequence.SkipTo (int)".
+			// When it comes true, iteration won't be done first.
 			while (left.MoveNext ()) {
-				bool skipThisItem = false;
-				// Examine all filters
-				foreach (ExprSequence expr in filter) {
-					bool doesntPass = true;
-					// Treat as OK if any of expr passed.
-					// FIXME: handle numeric predicate.
-					foreach (ExprSingle single in expr) {
-						if (single.EvaluateAsBoolean (left)) {
+				bool doesntPass = true;
+				// Treat as OK if any of filter expr passed.
+				// FIXME: handle numeric predicate.
+				foreach (ExprSingle single in filter) {
+					XPathAtomicValue av = single.EvaluateAsAtomic (left);
+					if (av == null)
+						continue;
+					if (SequenceType.IsNumeric (av.XmlType.TypeCode)) {
+						// numeric filter
+						if (av.ValueAsInt32 == left.Position) {
 							doesntPass = false;
 							break;
 						}
 					}
-					if (doesntPass) {
-						skipThisItem = true;
+					else if (single.EvaluateAsBoolean (left)) {
+						doesntPass = false;
 						break;
 					}
 				}
-				if (skipThisItem)
+				if (doesntPass)
 					continue;
 				return true;
 			}

+ 15 - 28
mcs/class/System.XML/System.Xml.Query/XQueryParser.jay

@@ -1649,13 +1649,10 @@ StepExpr // returns ExprSingle
 	;
 
 AxisStep // returns PathExpr 
-	: ForwardOrReverseStep Predicates
+	: ForwardOrReverseStep
+	| AxisStep Predicate
 	{
-		PredicateList p = (PredicateList) $2;
-		if (p == null)
-			$$ = $1;
-		else
-			$$ = new FilterStepExpr ((ExprSingle) $1, (PredicateList) $2);
+		$$ = new FilterStepExpr ((ExprSingle) $1, (ExprSequence) $2);
 	}
 	;
 
@@ -1664,13 +1661,20 @@ ForwardOrReverseStep // returns ExprSingle
 	| ReverseStep
 	;
 
+Predicate
+	: OPEN_BRACKET Expr CLOSE_BRACKET {
+		tokenizer.State = ParseState.Operator;
+	  }
+	{
+		$$ = $2;
+	}
+	;
+
 FilterStep // returns ExprSingle 
-	: PrimaryExpr Predicates
+	: PrimaryExpr
+	| FilterStep Predicate
 	{
-		if ($2 == null)
-			$$ = (ExprSingle) $1;
-		else
-			$$ = new FilterStepExpr ((ExprSingle) $1, (PredicateList) $2);
+		$$ = new FilterStepExpr ((ExprSingle) $1, (ExprSequence) $2);
 	}
 	;
 
@@ -1764,23 +1768,6 @@ AbbrevReverseStep // returns AxisStepExpr
 	}
 	;
 
-Predicates // returns PredicateList or null 
-	: // empty
-	{
-		$$ = null;
-	}
-	| OPEN_BRACKET Expr CLOSE_BRACKET {
-		tokenizer.State = ParseState.Operator;
-	  } Predicates
-	{
-		PredicateList l = (PredicateList) $5;
-		if (l == null)
-			l = new PredicateList ();
-		l.Insert (0, (ExprSequence) $2);
-		$$ = l;
-	}
-	;
-
 NodeTest // returns NodeTest
 	: KindTest
 	{