Merge pull request #960 from ermshiperete/ShowHelp
[mono.git] / mcs / class / System.XML / Mono.Xml.Xsl.Operations / XslForEach.cs
index 6530da87e5bab98f4b36d52b8f49f626659a0ddd..5b691c2e5f86f92d95c3c21965befbf3edad36bc 100644 (file)
@@ -40,13 +40,20 @@ namespace Mono.Xml.Xsl.Operations {
        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;
@@ -60,28 +67,41 @@ namespace Mono.Xml.Xsl.Operations {
                                                { 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 ();
+                       }
                }
        }
 }