Author: atsushi
Date: 2005-03-23 09:08:32 -0500 (Wed, 23 Mar 2005)
New Revision: 42144

Modified:
   trunk/mcs/class/System.XML/Mono.Xml.Xsl/ChangeLog
   trunk/mcs/class/System.XML/Mono.Xml.Xsl/Compiler.cs
   trunk/mcs/class/System.XML/Mono.Xml.Xsl/XslStylesheet.cs
   trunk/mcs/class/System.XML/Mono.Xml.Xsl/XsltCompiledContext.cs
Log:
2005-03-23  Atsushi Enomoto  <[EMAIL PROTECTED]>

        * XslStylesheet.cs :
          Variables are stored per stylesheet and added to compiler after
          all of the contents are processed (handle import precedence).
          Imports are now processed in prior to other contents (incorrect
          imports are now rejected). After imports, process includes to 
          process nested imports. In-process included stylesheets are 
          temporarily stored in including stylesheet.
          Handle keys like variables are handled.
          Added Compile() that is splitted from .ctor().
        * Compiler.cs :
          Store keys in compiler and compiled stylesheet.
          Duplicate variables in imports are now overriden as expected.
        * XsltCompiledContext.cs : use CompiledStylesheet.ResolveKey().




Modified: trunk/mcs/class/System.XML/Mono.Xml.Xsl/ChangeLog
===================================================================
--- trunk/mcs/class/System.XML/Mono.Xml.Xsl/ChangeLog   2005-03-23 13:30:10 UTC 
(rev 42143)
+++ trunk/mcs/class/System.XML/Mono.Xml.Xsl/ChangeLog   2005-03-23 14:08:32 UTC 
(rev 42144)
@@ -1,3 +1,19 @@
+2005-03-23  Atsushi Enomoto  <[EMAIL PROTECTED]>
+
+       * XslStylesheet.cs :
+         Variables are stored per stylesheet and added to compiler after
+         all of the contents are processed (handle import precedence).
+         Imports are now processed in prior to other contents (incorrect
+         imports are now rejected). After imports, process includes to 
+         process nested imports. In-process included stylesheets are 
+         temporarily stored in including stylesheet.
+         Handle keys like variables are handled.
+         Added Compile() that is splitted from .ctor().
+       * Compiler.cs :
+         Store keys in compiler and compiled stylesheet.
+         Duplicate variables in imports are now overriden as expected.
+       * XsltCompiledContext.cs : use CompiledStylesheet.ResolveKey().
+
 2005-03-22  Atsushi Enomoto  <[EMAIL PROTECTED]>
 
        * XslTransformProcessor.cs : now it looks safe to remove SetContext()

Modified: trunk/mcs/class/System.XML/Mono.Xml.Xsl/Compiler.cs
===================================================================
--- trunk/mcs/class/System.XML/Mono.Xml.Xsl/Compiler.cs 2005-03-23 13:30:10 UTC 
(rev 42143)
+++ trunk/mcs/class/System.XML/Mono.Xml.Xsl/Compiler.cs 2005-03-23 14:08:32 UTC 
(rev 42144)
@@ -97,6 +97,11 @@
                        return (XslGeneralVariable)globalVariables [name];
                }
                
+               public XslKey ResolveKey (QName name)
+               {
+                       return (XslKey) keys [name];
+               }
+               
                public XslAttributeSet ResolveAttributeSet (QName name)
                {
                        return (XslAttributeSet)attrSets [name];
@@ -112,6 +117,7 @@
                Stack styleStack = new Stack ();
                XslStylesheet currentStyle;
                
+               Hashtable keys = new Hashtable ();
                Hashtable globalVariables = new Hashtable ();
                Hashtable attrSets = new Hashtable ();
        
@@ -150,14 +156,15 @@
                                nav.MoveToParent ();
                        }
                        try {
-                               this.rootStyle = new XslStylesheet (this);
+                               rootStyle = new XslStylesheet ();
+                               rootStyle.Compile (this);
                        } catch (XsltCompileException) {
                                throw;
                        } catch (Exception x) {
                                throw new XsltCompileException ("XSLT compile 
error. " + x.Message, x,  Input);
                        }
                        
-                       return new CompiledStylesheet (rootStyle, 
globalVariables, attrSets, exprStore, nsMgr, rootStyle.Keys, outputs, 
decimalFormats, msScripts);
+                       return new CompiledStylesheet (rootStyle, 
globalVariables, attrSets, exprStore, nsMgr, keys, outputs, decimalFormats, 
msScripts);
                }
                
                MSXslScriptManager msScripts = new MSXslScriptManager ();
@@ -220,7 +227,7 @@
                        }
                }
                
-               private void PushInputDocument (XPathNavigator nav)
+               public void PushInputDocument (XPathNavigator nav)
                {
                        // Inclusion nest check
                        IXmlLineInfo li = currentInput as IXmlLineInfo;
@@ -392,7 +399,12 @@
                {
                        globalVariables [var.Name] = var;
                }
-               
+
+               public void AddKey (XslKey key)
+               {
+                       keys [key.Name] = key;
+               }
+
                public void AddAttributeSet (XslAttributeSet set)
                {
                        XslAttributeSet existing = attrSets [set.Name] as 
XslAttributeSet;
@@ -598,6 +610,7 @@
        }
        
        internal class VariableScope {
+               ArrayList variableNames;
                Hashtable variables;
                VariableScope parent;
                int nextSlot = 0;
@@ -622,10 +635,15 @@
                
                public int AddVariable (XslLocalVariable v)
                {
-                       if (variables == null)
+                       if (variables == null) {
+                               variableNames = new ArrayList ();
                                variables = new Hashtable ();
-                       
+                       }
                        variables [v.Name] = v;
+                       int idx = variableNames.IndexOf (v.Name);
+                       if (idx >= 0)
+                               return idx;
+                       variableNames.Add (v.Name);
                        return nextSlot++;
                }
                

Modified: trunk/mcs/class/System.XML/Mono.Xml.Xsl/XslStylesheet.cs
===================================================================
--- trunk/mcs/class/System.XML/Mono.Xml.Xsl/XslStylesheet.cs    2005-03-23 
13:30:10 UTC (rev 42143)
+++ trunk/mcs/class/System.XML/Mono.Xml.Xsl/XslStylesheet.cs    2005-03-23 
14:08:32 UTC (rev 42144)
@@ -59,6 +59,8 @@
                Hashtable parameters = new Hashtable ();
                // [QName]=>XslKey
                Hashtable keys = new Hashtable();
+               // [QName]=>XslVariable
+               Hashtable variables = new Hashtable ();
 
                XslTemplateTable templates;
 
@@ -68,6 +70,11 @@
                XmlQualifiedName [] excludeResultPrefixes;
                ArrayList stylesheetNamespaces = new ArrayList ();
 
+               // in-process includes. They must be first parsed as
+               // XPathNavigator, collected imports, and then processed
+               // other content.
+               Hashtable inProcessIncludes = new Hashtable ();
+
                public XmlQualifiedName [] ExtensionElementPrefixes {
                        get { return extensionElementPrefixes; }
                }
@@ -100,16 +107,16 @@
                        get { return templates; }
                }
 
-               public Hashtable Keys {
-                       get { return keys; }
-               }
-
                public string Version {
                        get { return version; }
                }
 
-               public XslStylesheet (Compiler c)
+               public XslStylesheet ()
                {
+               }
+
+               internal void Compile (Compiler c)
+               {
                        c.PushStylesheet (this);
                        
                        templates = new XslTemplateTable (this);
@@ -123,7 +130,7 @@
                                if (c.Input.GetAttribute ("version", 
XsltNamespace) == String.Empty)
                                        throw new XsltCompileException 
("Mandatory global attribute version is missing.", null, c.Input);
                                // then it is simplified stylesheet.
-                               Templates.Add (new XslTemplate (c));
+                               templates.Add (new XslTemplate (c));
                        } else {
                                if (c.Input.LocalName != "stylesheet" &&
                                        c.Input.LocalName != "transform")
@@ -145,8 +152,14 @@
                                }
                                ProcessTopLevelElements (c);
                        }
-                       
+
+                       foreach (XslGlobalVariable v in variables.Values)
+                               c.AddGlobalVariable (v);
+                       foreach (XslKey key in keys.Values)
+                               c.AddKey (key);
+
                        c.PopStylesheet ();
+                       inProcessIncludes = null;
                }
 
                private QName [] ParseMappedPrefixes (string list, 
XPathNavigator nav)
@@ -168,19 +181,6 @@
                        return (QName []) al.ToArray (typeof (QName));
                }
 
-               public XslKey FindKey (QName name)
-               {
-                       XslKey key = Keys [name] as XslKey;
-                       if (key != null)
-                               return key;
-                       for (int i = Imports.Count - 1; i >= 0; i--) {
-                               key = ((XslStylesheet) Imports [i]).FindKey 
(name);
-                               if (key != null)
-                                       return key;
-                       }
-                       return null;
-               }
-
                bool countedSpaceControlExistence;
                bool cachedHasSpaceControls;
                static readonly QName allMatchName = new QName ("*");
@@ -319,36 +319,81 @@
                        return result != null ? result : prefix;
                }
 
-               private XslStylesheet (Compiler c, XslStylesheet importer) : 
this (c)
+               private void StoreInclude (Compiler c)
                {
-//                     this.importer = importer;
+                       XPathNavigator including = c.Input.Clone ();
+                       c.PushInputDocument (c.Input.GetAttribute ("href", 
String.Empty));
+                       inProcessIncludes [including] = c.Input;
+
+                       HandleImportsInInclude (c);
+                       c.PopInputDocument ();
                }
-               
-               private void HandleInclude (Compiler c, string href)
+
+               private void HandleImportsInInclude (Compiler c)
                {
-                       c.PushInputDocument (href);
+                       if (c.Input.NamespaceURI != XsltNamespace) {
+                               if (c.Input.GetAttribute ("version",
+                                       XsltNamespace) == String.Empty)
+                                       throw new XsltCompileException 
("Mandatory global attribute version is missing.", null, c.Input);
+                               // simplified style == never imports.
+                               // Keep this position
+                               return;
+                       }
 
-                       // move to root element
+                       if (!c.Input.MoveToFirstChild ()) {
+                               c.Input.MoveToRoot ();
+                               return;
+                       }
+
+                       HandleIncludesImports (c);
+               }
+
+               private void HandleInclude (Compiler c)
+               {
+                       XPathNavigator included = null;
+                       foreach (XPathNavigator inc in inProcessIncludes.Keys) {
+                               if (inc.IsSamePosition (c.Input)) {
+                                       included = (XPathNavigator) 
inProcessIncludes [inc];
+                                       break;
+                               }
+                       }
+                       if (included == null)
+                               throw new Exception ("Should not happen. 
Current input is " + c.Input.BaseURI + " / " + c.Input.Name + ", " + 
inProcessIncludes.Count);
+
+                       if (included.NodeType == XPathNodeType.Root)
+                               return; // Already done.
+
+                       c.PushInputDocument (included);
+
                        while (c.Input.NodeType != XPathNodeType.Element)
                                if (!c.Input.MoveToNext ())
-                                       throw new XsltCompileException 
("Stylesheet root element must be either \"stylesheet\" or \"transform\" or any 
literal element.", null, c.Input);
+                                       break;
 
-                       if (c.Input.NamespaceURI != XsltNamespace) {
-                               if (c.Input.GetAttribute ("version", 
XsltNamespace) == String.Empty)
-                                       throw new XsltCompileException 
("Mandatory global attribute version is missing.", null, c.Input);
+                       if (c.Input.NamespaceURI != XsltNamespace &&
+                               c.Input.NodeType == XPathNodeType.Element) {
                                // then it is simplified stylesheet.
-                               Templates.Add (new XslTemplate (c));
+                               templates.Add (new XslTemplate (c));
                        }
-                       else
-                               ProcessTopLevelElements (c);
+                       else {
+                               do {
+                                       if (c.Input.NodeType != 
XPathNodeType.Element)
+                                               continue;
+                                       Debug.EnterNavigator (c);
+                                       HandleTopLevelElement (c);
+                                       Debug.ExitNavigator (c);
+                               } while (c.Input.MoveToNext ());
+                       }
 
+                       c.Input.MoveToParent ();
                        c.PopInputDocument ();
                }
                
                private void HandleImport (Compiler c, string href)
                {
                        c.PushInputDocument (href);
-                       imports.Add (new XslStylesheet (c, this));
+                       XslStylesheet imported = new XslStylesheet ();
+                       imported.Compile (c);
+                       imports.Add (imported);
                        c.PopInputDocument ();
                }
                
@@ -358,15 +403,11 @@
                        switch (n.NamespaceURI)
                        {
                        case XsltNamespace:
-                               
                                switch (n.LocalName)
                                {
                                case "include":
-                                       HandleInclude (c, c.GetAttribute 
("href"));
+                                       HandleInclude (c);
                                        break;
-                               case "import":
-                                       HandleImport (c, c.GetAttribute 
("href"));
-                                       break;
                                case "preserve-space":
                                        AddSpaceControls 
(c.ParseQNameListAttribute ("elements"), XmlSpace.Preserve, n);
                                        break;
@@ -383,7 +424,8 @@
                                        break;
 
                                case "key":
-                                       keys [c.ParseQNameAttribute ("name")] = 
new XslKey (c);
+                                       XslKey key = new XslKey (c);
+                                       keys [key.Name] = key;
                                        break;
                                        
                                case "output":
@@ -398,14 +440,16 @@
                                        templates.Add (new XslTemplate (c));    
                                        break;
                                case "variable":
-                                       c.AddGlobalVariable (new 
XslGlobalVariable (c));
+                                       XslGlobalVariable gvar = new 
XslGlobalVariable (c);
+                                       variables [gvar.Name] = gvar;
                                        break;
                                case "param":
-                                       c.AddGlobalVariable (new XslGlobalParam 
(c));
+                                       XslGlobalParam gpar = new 
XslGlobalParam (c);
+                                       variables [gpar.Name] = gpar;
                                        break;
                                default:
                                        if (version == "1.0")
-                                               throw new XsltCompileException 
("Unrecognized top level element.", null, c.Input);
+                                               throw new XsltCompileException 
("Unrecognized top level element after imports.", null, c.Input);
                                        break;
                                }
                                break;
@@ -419,11 +463,48 @@
                                break;
                        }
                }
-               
+
+               private XPathNavigator HandleIncludesImports (Compiler c)
+               {
+                       // process imports. They must precede to other
+                       // top level elements by schema.
+                       do {
+                               if (c.Input.NodeType != XPathNodeType.Element)
+                                       continue;
+                               if (c.Input.LocalName != "import" ||
+                                       c.Input.NamespaceURI != XsltNamespace)
+                                       break;
+                               Debug.EnterNavigator (c);
+                               HandleImport (c, c.GetAttribute ("href"));
+                               Debug.ExitNavigator (c);
+                       } while (c.Input.MoveToNext ());
+
+                       XPathNavigator saved = c.Input.Clone ();
+
+                       // process includes to handle nested imports. They must 
precede to other
+                       // top level elements by schema.
+                       do {
+                               if (c.Input.NodeType != XPathNodeType.Element ||
+                                       c.Input.LocalName != "include" ||
+                                       c.Input.NamespaceURI != XsltNamespace)
+                                       continue;
+                               Debug.EnterNavigator (c);
+                               StoreInclude (c);
+                               Debug.ExitNavigator (c);
+                       } while (c.Input.MoveToNext ());
+
+                       c.Input.MoveTo (saved);
+
+                       return saved;
+               }
+
                private void ProcessTopLevelElements (Compiler c)
                {
                        if (!c.Input.MoveToFirstChild ())
                                return;
+
+                       XPathNavigator saved = HandleIncludesImports (c);
+
                        do {
                                // Collect namespace aliases first.
                                if (c.Input.NodeType != XPathNodeType.Element ||
@@ -439,7 +520,7 @@
                                namespaceAliases.Set (sprefix, rprefix);
                        } while (c.Input.MoveToNext ());
 
-                       c.Input.MoveToFirst ();
+                       c.Input.MoveTo (saved);
                        do {
                                if (c.Input.NodeType != XPathNodeType.Element)
                                        continue;

Modified: trunk/mcs/class/System.XML/Mono.Xml.Xsl/XsltCompiledContext.cs
===================================================================
--- trunk/mcs/class/System.XML/Mono.Xml.Xsl/XsltCompiledContext.cs      
2005-03-23 13:30:10 UTC (rev 42143)
+++ trunk/mcs/class/System.XML/Mono.Xml.Xsl/XsltCompiledContext.cs      
2005-03-23 14:08:32 UTC (rev 42144)
@@ -128,7 +128,7 @@
                        KeyIndexTable table =
                                keyIndexTables [name] as KeyIndexTable;
                        if (table == null) {
-                               table = new KeyIndexTable (this, 
p.CompiledStyle.Style.FindKey (name));
+                               table = new KeyIndexTable (this, 
p.CompiledStyle.ResolveKey (name));
                                keyIndexTables [name] = table;
                        }
                        return table;

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to