internal class XslForEach : XslCompiledElement {
XPathExpression select;
XslOperation children;
+ XslSortEvaluator sortEvaluator;
public XslForEach (Compiler c) : base (c) {}
protected override void Compile (Compiler c)
{
+ if (c.Debugger != null)
+ c.Debugger.DebugCompile (c.Input);
+
+ c.CheckExtraAttributes ("for-each", "select");
+
c.AssertAttribute ("select");
select = c.CompileExpression (c.GetAttribute ("select"));
+ ArrayList sorterList = null;
if (c.Input.MoveToFirstChild ()) {
bool alldone = true;
{ alldone = false; break; }
if (c.Input.LocalName != "sort")
{ alldone = false; break; }
-
- c.AddSort (select, new Sort (c));
-
+ //c.AddSort (select, new Sort (c));
+ if (sorterList == null)
+ sorterList = new ArrayList ();
+ sorterList.Add (new Sort (c));
} while (c.Input.MoveToNext ());
if (!alldone)
children = c.CompileTemplateContent ();
c.Input.MoveToParent ();
}
+ if (sorterList != null)
+ sortEvaluator = new XslSortEvaluator (select,
+ (Sort []) sorterList.ToArray (typeof (Sort)));
}
public override void Evaluate (XslTransformProcessor p)
{
- if (children == null)
- return;
+ if (p.Debugger != null)
+ p.Debugger.DebugExecute (p, this.DebugInput);
+
+ // This intelligent optimization causes poor compatibility bug shown in bug #457065
+// if (children == null)
+// return;
+
+ XPathNodeIterator iter = sortEvaluator != null ?
+ sortEvaluator.SortedSelect (p) :
+ p.Select (select);
- p.PushNodeset (p.Select (select));
- p.PushForEachContext ();
- while (p.NodesetMoveNext ())
+ while (p.NodesetMoveNext (iter)) {
+ p.PushNodeset (iter);
+ p.PushForEachContext ();
children.Evaluate (p);
- p.PopForEachContext();
- p.PopNodeset ();
+ p.PopForEachContext();
+ p.PopNodeset ();
+ }
}
}
}