System.Drawing: added email to icon and test file headers
[mono.git] / mcs / class / System.XML / Mono.Xml.Xsl / XslKey.cs
index 1e97bf03ee58b0e77a9c543edc748045ba52f518..d3f1103ff8393b4095d2b3d0bd79a45069dd2475 100644 (file)
@@ -99,21 +99,26 @@ namespace Mono.Xml.Xsl
        internal class KeyIndexTable
        {
                XsltCompiledContext ctx;
-               XslKey key;
-               Hashtable map;
+               ArrayList keys;
                Hashtable mappedDocuments;
 
-               public KeyIndexTable (XsltCompiledContext ctx, XslKey key)
+               public KeyIndexTable (XsltCompiledContext ctx, ArrayList keys)
                {
                        this.ctx = ctx;
-                       this.key = key;
+                       this.keys = keys;
                }
 
-               public XslKey Key {
-                       get { return key; }
+               public ArrayList Keys {
+                       get { return keys; }
                }
 
-               private void CollectTable (XPathNavigator doc, XsltContext ctx)
+               private void CollectTable (XPathNavigator doc, XsltContext ctx, Hashtable map)
+               {
+                       for (int i = 0; i < keys.Count; i++)
+                               CollectTable (doc, ctx, map, (XslKey) keys[i]);
+               }
+
+               private void CollectTable (XPathNavigator doc, XsltContext ctx, Hashtable map, XslKey key)
                {
                        XPathNavigator nav = doc.Clone ();
                        nav.MoveToRoot ();
@@ -130,7 +135,7 @@ namespace Mono.Xml.Xsl
                        do {
                                if (key.Match.Matches (nav, ctx)) {
                                        tmp.MoveTo (nav);
-                                       CollectIndex (nav, tmp);
+                                       CollectIndex (nav, tmp, map);
                                }
                        } while (MoveNavigatorToNext (nav, matchesAttributes));
                        if (map != null)
@@ -159,33 +164,39 @@ namespace Mono.Xml.Xsl
                        return false;
                }
 
-               private void CollectIndex (XPathNavigator nav, XPathNavigator target)
+               private void CollectIndex (XPathNavigator nav, XPathNavigator target, Hashtable map)
+               {
+                       for (int i = 0; i < keys.Count; i++)
+                               CollectIndex (nav, target, map, (XslKey) keys[i]);
+               }
+
+               private void CollectIndex (XPathNavigator nav, XPathNavigator target, Hashtable map, XslKey key)
                {
                        XPathNodeIterator iter;
                        switch (key.Use.ReturnType) {
                        case XPathResultType.NodeSet:
                                iter = nav.Select (key.Use);
                                while (iter.MoveNext ())
-                                       AddIndex (iter.Current.Value, target);
+                                       AddIndex (iter.Current.Value, target, map);
                                break;
                        case XPathResultType.Any:
                                object o = nav.Evaluate (key.Use);
                                iter = o as XPathNodeIterator;
                                if (iter != null) {
                                        while (iter.MoveNext ())
-                                               AddIndex (iter.Current.Value, target);
+                                               AddIndex (iter.Current.Value, target, map);
                                }
                                else
-                                       AddIndex (XPathFunctions.ToString (o), target);
+                                       AddIndex (XPathFunctions.ToString (o), target, map);
                                break;
                        default:
                                string keyValue = nav.EvaluateString (key.Use, null, null);
-                               AddIndex (keyValue, target);
+                               AddIndex (keyValue, target, map);
                                break;
                        }
                }
 
-               private void AddIndex (string key, XPathNavigator target)
+               private void AddIndex (string key, XPathNavigator target, Hashtable map)
                {
                        ArrayList al = map [key] as ArrayList;
                        if (al == null) {
@@ -200,13 +211,13 @@ namespace Mono.Xml.Xsl
 
                private ArrayList GetNodesByValue (XPathNavigator nav, string value, XsltContext ctx)
                {
-                       if (map == null) {
+                       if (mappedDocuments == null)
                                mappedDocuments = new Hashtable ();
+                       Hashtable map = (Hashtable) mappedDocuments [nav.BaseURI];
+                       if (map == null) {
                                map = new Hashtable ();
-                       }
-                       if (!mappedDocuments.ContainsKey (nav.BaseURI)) {
-                               mappedDocuments.Add (nav.BaseURI, nav.BaseURI);
-                               CollectTable (nav, ctx);
+                               mappedDocuments.Add (nav.BaseURI, map);
+                               CollectTable (nav, ctx, map);
                        }
                        
                        return map [value] as ArrayList;
@@ -255,7 +266,7 @@ namespace Mono.Xml.Xsl
                                                        iter, result, tmp);
                                }
                        }
-                       else {
+                       else if (nav != null) {
                                ArrayList nodes = GetNodesByValue (
                                        nav, XPathFunctions.ToString (o), ctx);
                                if (nodes != null)