2003-11-19 Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
authorAtsushi Eno <atsushieno@gmail.com>
Wed, 19 Nov 2003 15:09:04 +0000 (15:09 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Wed, 19 Nov 2003 15:09:04 +0000 (15:09 -0000)
* Compiler.cs : Changed Keys from ArrayList to Hashtable.
  XslStylesheet.cs : Added Keys support here.
* XslTransformProcessor.cs : Should call SetContext() to expressions
  before evaluating current nodes.
* XsltCompiledContext.cs : 1) XsltDocument.GetDocument() should use
  xsltContext. 2) XsltKey exposes KeyName, Field and NamespaceManager
  for KeyPattern. It now uses CompiledStyle.FindKeys().

svn path=/trunk/mcs/; revision=20222

mcs/class/System.XML/Mono.Xml.Xsl/ChangeLog
mcs/class/System.XML/Mono.Xml.Xsl/Compiler.cs
mcs/class/System.XML/Mono.Xml.Xsl/XslStylesheet.cs
mcs/class/System.XML/Mono.Xml.Xsl/XslTransformProcessor.cs
mcs/class/System.XML/Mono.Xml.Xsl/XsltCompiledContext.cs

index 48e476ca09be6d09ecae460f15db9e762eb05ee3..29a661619e37c0431e8c48875daf9cbf7fee7d86 100644 (file)
@@ -1,3 +1,13 @@
+2003-11-19 Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
+
+       * Compiler.cs : Changed Keys from ArrayList to Hashtable.
+         XslStylesheet.cs : Added Keys support here.
+       * XslTransformProcessor.cs : Should call SetContext() to expressions
+         before evaluating current nodes.
+       * XsltCompiledContext.cs : 1) XsltDocument.GetDocument() should use
+         xsltContext. 2) XsltKey exposes KeyName, Field and NamespaceManager
+         for KeyPattern. It now uses CompiledStyle.FindKeys().
+
 2003-11-13 Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
 
        * GenericOutputter.cs : Added HTML output support. Closer xmlns handling
index 9f68f44acc0a395deeb155cfd86010252b769afb..392925daac18a2b9481ae7301fa3be5b6eb81bf5 100644 (file)
@@ -33,11 +33,11 @@ namespace Mono.Xml.Xsl {
                Hashtable attrSets;
                ExpressionStore exprStore;
                XmlNamespaceManager nsMgr;
-               ArrayList keys;
+               Hashtable keys;
                Hashtable outputs;
                Hashtable decimalFormats;
                
-               public CompiledStylesheet (XslStylesheet style, Hashtable globalVariables, Hashtable attrSets, ExpressionStore exprStore, XmlNamespaceManager nsMgr, ArrayList keys, Hashtable outputs, Hashtable decimalFormats)
+               public CompiledStylesheet (XslStylesheet style, Hashtable globalVariables, Hashtable attrSets, ExpressionStore exprStore, XmlNamespaceManager nsMgr, Hashtable keys, Hashtable outputs, Hashtable decimalFormats)
                {
                        this.style = style;
                        this.globalVariables = globalVariables;
@@ -52,7 +52,7 @@ namespace Mono.Xml.Xsl {
                public XslStylesheet Style { get { return style; }}
                public ExpressionStore ExpressionStore {get{return exprStore;}}
                public XmlNamespaceManager NamespaceManager {get{return nsMgr;}}
-               public ArrayList Keys {get { return keys;}}
+               public Hashtable Keys {get { return keys;}}
                public Hashtable Outputs { get { return outputs; }}
                
                public XslDecimalFormat LookupDecimalFormat (QName name)
@@ -117,7 +117,7 @@ namespace Mono.Xml.Xsl {
                        }
                        this.rootStyle = new XslStylesheet (this);
                        
-                       return new CompiledStylesheet (rootStyle, globalVariables, attrSets, exprStore, nsMgr, keys, outputs, decimalFormats);
+                       return new CompiledStylesheet (rootStyle, globalVariables, attrSets, exprStore, nsMgr, rootStyle.Keys, outputs, decimalFormats);
                }
                
 #region Input
@@ -398,15 +398,6 @@ namespace Mono.Xml.Xsl {
                }
 #endregion
                
-#region Key
-               ArrayList keys = new ArrayList ();
-               
-               public void AddKeyPattern (XslKey key)
-               {
-                       keys.Add (key);
-               }
-#endregion
-               
 #region Decimal Format
                Hashtable decimalFormats = new Hashtable ();
                
index acd011c64ecca366c5725718cb6cb6cd10b07538..77cf2c9122ec33773dde91f192f9f88e68b4a4bb 100644 (file)
 // (C) 2003 Ben Maurer
 // (C) 2003 Atsushi Enomoto
 //
-\r
-using System;\r
-using System.CodeDom;\r
+
+using System;
+using System.CodeDom;
 using System.Collections;
-using System.Collections.Specialized;\r
-using System.Xml;\r
-using System.Xml.Schema;\r
-using System.Xml.XPath;\r
+using System.Collections.Specialized;
+using System.Xml;
+using System.Xml.Schema;
+using System.Xml.XPath;
 using System.Xml.Xsl;
 using System.IO;
 
 using Mono.Xml.Xsl.Operations;
-\r
-using QName = System.Xml.XmlQualifiedName;\r
-
-namespace Mono.Xml.Xsl {\r
-\r
-       public class XslStylesheet {\r
-               public const string XsltNamespace = "http://www.w3.org/1999/XSL/Transform";\r
-               public const string MSXsltNamespace = "urn:schemas-microsoft-com:xslt::script";\r
+
+using QName = System.Xml.XmlQualifiedName;
+
+namespace Mono.Xml.Xsl {
+
+       public class XslStylesheet {
+               public const string XsltNamespace = "http://www.w3.org/1999/XSL/Transform";
+               public const string MSXsltNamespace = "urn:schemas-microsoft-com:xslt::script";
                
-               Compiler c;\r
-
-               XslStylesheet importer;\r
-               // Top-level elements\r
-               ArrayList imports = new ArrayList ();\r
-               // [QName]=>XmlSpace\r
-               Hashtable spaceControls = new Hashtable ();\r
-               // [string stylesheet-prefix]=>string result-prefix\r
-               Hashtable namespaceAliases = new Hashtable ();\r
-               // [QName]=>XmlSpace\r
-               Hashtable parameters = new Hashtable ();\r
-               \r
-               MSXslScriptManager msScripts = new MSXslScriptManager ();\r
-               XslTemplateTable templates;\r
-\r
-               // stylesheet attributes\r
-               string version;\r
-               XmlQualifiedName [] extensionElementPrefixes;\r
-               XmlQualifiedName [] excludeResultPrefixes;\r
-               StringDictionary stylesheetNamespaces = new StringDictionary ();\r
-\r
-               // below are newly introduced in XSLT 2.0\r
-               //  elements::\r
-               // xsl:import-schema should be interpreted into it.\r
-               XmlSchemaCollection schemas = new XmlSchemaCollection ();\r
-               // [QName]=>XslCharacterMap\r
-               Hashtable characterMap = new Hashtable ();\r
-               // [QName]=>XslDateFormat\r
-               Hashtable dateFormats = new Hashtable ();\r
-               // [QName]=>XslFunction\r
-               Hashtable functions = new Hashtable ();\r
-               // [QName]=>XslSortKey\r
-               Hashtable sortKeys = new Hashtable ();\r
-               //  attributes::\r
-               string xpathDefaultNamespace = "";\r
-               XslDefaultValidation defaultValidation = XslDefaultValidation.Lax;\r
-\r
-               public XmlQualifiedName [] ExtensionElementPrefixes {\r
-                       get { return extensionElementPrefixes; }\r
-               }\r
-\r
-               public XmlQualifiedName [] ExcludeResultPrefixes {\r
-                       get { return excludeResultPrefixes; }\r
-               }\r
-\r
-               public StringDictionary StylesheetNamespaces {\r
-                       get { return stylesheetNamespaces; }\r
-               }\r
-\r
-               public ArrayList Imports {\r
-                       get { return imports; }\r
-               }\r
-\r
-               public Hashtable SpaceControls {\r
-                       get { return spaceControls; }\r
-               }\r
-\r
-               public Hashtable NamespaceAliases {\r
-                       get { return namespaceAliases; }\r
-               }\r
-
-               public Hashtable Parameters {\r
-                       get { return parameters; }\r
-               }
-\r
-               public MSXslScriptManager ScriptManager{\r
-                       get { return msScripts; }\r
-               }\r
-\r
-               public XslTemplateTable Templates {\r
-                       get { return templates; }\r
-               }\r
-
-\r
-               public XslStylesheet (Compiler c)\r
+               Compiler c;
+
+               XslStylesheet importer;
+               // Top-level elements
+               ArrayList imports = new ArrayList ();
+               // [QName]=>XmlSpace
+               Hashtable spaceControls = new Hashtable ();
+               // [string stylesheet-prefix]=>string result-prefix
+               Hashtable namespaceAliases = new Hashtable ();
+               // [QName]=>XmlSpace
+               Hashtable parameters = new Hashtable ();
+               // [QName]=>XslKey
+               Hashtable keys = new Hashtable();
+
+               MSXslScriptManager msScripts = new MSXslScriptManager ();
+               XslTemplateTable templates;
+
+               // stylesheet attributes
+               string version;
+               XmlQualifiedName [] extensionElementPrefixes;
+               XmlQualifiedName [] excludeResultPrefixes;
+               StringDictionary stylesheetNamespaces = new StringDictionary ();
+
+               // below are newly introduced in XSLT 2.0
+               //  elements::
+               // xsl:import-schema should be interpreted into it.
+               XmlSchemaCollection schemas = new XmlSchemaCollection ();
+               // [QName]=>XslCharacterMap
+               Hashtable characterMap = new Hashtable ();
+               // [QName]=>XslDateFormat
+               Hashtable dateFormats = new Hashtable ();
+               // [QName]=>XslFunction
+               Hashtable functions = new Hashtable ();
+               // [QName]=>XslSortKey
+               Hashtable sortKeys = new Hashtable ();
+               //  attributes::
+               string xpathDefaultNamespace = "";
+               XslDefaultValidation defaultValidation = XslDefaultValidation.Lax;
+
+               public XmlQualifiedName [] ExtensionElementPrefixes {
+                       get { return extensionElementPrefixes; }
+               }
+
+               public XmlQualifiedName [] ExcludeResultPrefixes {
+                       get { return excludeResultPrefixes; }
+               }
+
+               public StringDictionary StylesheetNamespaces {
+                       get { return stylesheetNamespaces; }
+               }
+
+               public ArrayList Imports {
+                       get { return imports; }
+               }
+
+               public Hashtable SpaceControls {
+                       get { return spaceControls; }
+               }
+
+               public Hashtable NamespaceAliases {
+                       get { return namespaceAliases; }
+               }
+
+               public Hashtable Parameters {
+                       get { return parameters; }
+               }
+
+               public MSXslScriptManager ScriptManager{
+                       get { return msScripts; }
+               }
+
+               public XslTemplateTable Templates {
+                       get { return templates; }
+               }
+
+               public Hashtable Keys {
+                       get { return keys; }
+               }
+
+               public XslStylesheet (Compiler c)
                {
                        this.c = c;
                        c.PushStylesheet (this);
                        
-                       templates = new XslTemplateTable (this);\r
-                       if (c.Input.NamespaceURI != XsltNamespace) {\r
-                               // then it is simplified stylesheet.\r
-                               Templates.Add (new XslTemplate (c));\r
-                       } else {\r
-                               version = c.Input.GetAttribute ("version", "");\r
-                               extensionElementPrefixes = c.ParseQNameListAttribute ("extension-element-prefixes");\r
-                               excludeResultPrefixes = c.ParseQNameListAttribute ("exclude-result-prefixes");\r
+                       templates = new XslTemplateTable (this);
+                       if (c.Input.NamespaceURI != XsltNamespace) {
+                               // then it is simplified stylesheet.
+                               Templates.Add (new XslTemplate (c));
+                       } else {
+                               version = c.Input.GetAttribute ("version", "");
+                               extensionElementPrefixes = c.ParseQNameListAttribute ("extension-element-prefixes");
+                               excludeResultPrefixes = c.ParseQNameListAttribute ("exclude-result-prefixes");
                                if (c.Input.MoveToFirstNamespace (XPathNamespaceScope.Local)) {
                                        do {
                                                if (c.Input.Value == XsltNamespace)
@@ -124,12 +129,25 @@ namespace Mono.Xml.Xsl {
                                        } while (c.Input.MoveToNextNamespace (XPathNamespaceScope.Local));
                                        c.Input.MoveToParent ();
                                }
-                               ProcessTopLevelElements ();\r
+                               ProcessTopLevelElements ();
                        }
                        
-                       c.PopStylesheet ();\r
+                       c.PopStylesheet ();
                }
                
+               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;
+               }
+
                private XslStylesheet (Compiler c, XslStylesheet importer) : this (c)
                {
                        this.importer = importer;
@@ -181,7 +199,7 @@ namespace Mono.Xml.Xsl {
                                        break;
 
                                case "key":
-                                       c.AddKeyPattern (new XslKey (c));
+                                       keys.Add (c.ParseQNameAttribute ("name"), new XslKey (c));
                                        break;
                                        
                                case "output":
@@ -213,10 +231,10 @@ namespace Mono.Xml.Xsl {
                                break;
                        }
                }
-               \r
-               private void ProcessTopLevelElements ()\r
+               
+               private void ProcessTopLevelElements ()
                {
-                       if (c.Input.MoveToFirstChild ()) {\r
+                       if (c.Input.MoveToFirstChild ()) {
                                do {
                                        if (c.Input.NodeType == XPathNodeType.Element) {                                        
                                                Debug.EnterNavigator (c);
@@ -226,23 +244,23 @@ namespace Mono.Xml.Xsl {
                                } while (c.Input.MoveToNext ());
                                
                                c.Input.MoveToParent ();
-                       }\r
-               }\r
-\r
-               private void AddSpaceControls (QName [] names, XmlSpace result, XPathNavigator styleElem)\r
-               {\r
-                       foreach (QName name in names)\r
-                               spaceControls.Add (name, result);\r
-               }\r
-\r
-       }\r
-\r
-       \r
-       public enum XslDefaultValidation\r
-       {\r
-               Strict,\r
-               Lax,\r
-               Preserve,\r
-               Strip\r
-       }\r
-}\r
+                       }
+               }
+
+               private void AddSpaceControls (QName [] names, XmlSpace result, XPathNavigator styleElem)
+               {
+                       foreach (QName name in names)
+                               spaceControls.Add (name, result);
+               }
+
+       }
+
+       
+       public enum XslDefaultValidation
+       {
+               Strict,
+               Lax,
+               Preserve,
+               Strip
+       }
+}
index def4b4c784d29a0ea535e77602a9d0c9e49fe9ad..1eddf56b1343c54a6f57b32dc16de9d0f90abd4c 100644 (file)
@@ -54,7 +54,8 @@ namespace Mono.Xml.Xsl {
                        this.resolver = resolver != null ? resolver : new XmlUrlResolver ();
                        this.outputStylesheetXmlns = true;
 
-                       PushNodeset (root.Select ("."));
+                       XPathExpression exp = root.Compile (".");
+                       PushNodeset (root.Select (exp, this.XPathContext));
                        
                        foreach (XslGlobalVariable v in CompiledStyle.Variables.Values) {
                                if (args != null && v is XslGlobalParam) {
@@ -70,7 +71,7 @@ namespace Mono.Xml.Xsl {
                        PopNodeset ();
                        
                        this.PushOutput (outputtter);
-                       this.ApplyTemplates (root.Select ("."), QName.Empty, null);
+                       this.ApplyTemplates (root.Select (exp, this.XPathContext), QName.Empty, null);
                        this.PopOutput ();
                }
                
@@ -327,7 +328,6 @@ namespace Mono.Xml.Xsl {
                }
                
                #endregion
-               
 
                public void PushForEachContext ()
                {
@@ -377,7 +377,8 @@ namespace Mono.Xml.Xsl {
                public object Evaluate (XPathExpression expr)
                {
                        expr = CompiledStyle.ExpressionStore.PrepForExecution (expr, this);
-                       
+                       expr.SetContext (XPathContext);
+
                        XPathNodeIterator itr = CurrentNodeset;
                        return itr.Current.Evaluate (expr, itr, XPathContext);
                }
@@ -385,6 +386,7 @@ namespace Mono.Xml.Xsl {
                public string EvaluateString (XPathExpression expr)
                {
                        expr = CompiledStyle.ExpressionStore.PrepForExecution (expr, this);
+                       expr.SetContext (XPathContext);
                        
                        XPathNodeIterator itr = CurrentNodeset;
                        return itr.Current.EvaluateString (expr, itr, XPathContext);
@@ -393,6 +395,7 @@ namespace Mono.Xml.Xsl {
                public bool EvaluateBoolean (XPathExpression expr)
                {
                        expr = CompiledStyle.ExpressionStore.PrepForExecution (expr, this);
+                       expr.SetContext (XPathContext);
                        
                        XPathNodeIterator itr = CurrentNodeset;
                        return itr.Current.EvaluateBoolean (expr, itr, XPathContext);
@@ -401,6 +404,7 @@ namespace Mono.Xml.Xsl {
                public double EvaluateNumber (XPathExpression expr)
                {
                        expr = CompiledStyle.ExpressionStore.PrepForExecution (expr, this);
+                       expr.SetContext (XPathContext);
                        
                        XPathNodeIterator itr = CurrentNodeset;
                        return itr.Current.EvaluateNumber (expr, itr, XPathContext);
@@ -409,6 +413,7 @@ namespace Mono.Xml.Xsl {
                public XPathNodeIterator Select (XPathExpression expr)
                {
                        expr = CompiledStyle.ExpressionStore.PrepForExecution (expr, this);
+                       expr.SetContext (XPathContext);
                        return CurrentNodeset.Current.Select (expr, XPathContext);
                }
                
index 20a4341852715ff10828868e45c0c6247f232c03..86da3e9c0c07d96ec7b1a233d28dfa6416bbdaf3 100644 (file)
@@ -342,7 +342,7 @@ namespace Mono.Xml.Xsl.Functions {
                        } else
                                n = xsltContext.Processor.GetDocument (uri);
                        
-                       return new SelfIterator (n, null);
+                       return new SelfIterator (n, xsltContext);
                }
        }
        
@@ -552,11 +552,13 @@ namespace Mono.Xml.Xsl.Functions {
                {
                        if (args == null || args.Tail == null)
                                throw new XPathException ("key takes 2 args");
-                       
                        arg0 = args.Arg;
                        arg1 = args.Tail.Arg;
                        nsm = ctx.GetNsm ();
                }
+               public Expression KeyName { get { return arg0; } }
+               public Expression Field { get { return arg1; } }
+               public XmlNamespaceManager NamespaceManager { get { return nsm; } }
                public override XPathResultType ReturnType { get { return XPathResultType.NodeSet; }}
                
                public override object Evaluate (BaseIterator iter)
@@ -580,22 +582,21 @@ namespace Mono.Xml.Xsl.Functions {
                {
                        XPathNavigator searchDoc = context.Clone ();
                        searchDoc.MoveToRoot ();
-                       foreach (XslKey key in xsltContext.Processor.CompiledStyle.Keys) {
-                               if (key.Name == name) {
-                                       XPathNodeIterator desc = searchDoc.SelectDescendants (XPathNodeType.All, true);
+                       XslKey key = xsltContext.Processor.CompiledStyle.Style.FindKey (name);
+                       if (key != null) {
+                               XPathNodeIterator desc = searchDoc.SelectDescendants (XPathNodeType.All, true);
 
-                                       while (desc.MoveNext ()) {
-                                               if (key.Matches (desc.Current, value))
-                                                       AddResult (result, desc.Current);
+                               while (desc.MoveNext ()) {
+                                       if (key.Matches (desc.Current, value))
+                                               AddResult (result, desc.Current);
+                                       
+                                       if (desc.Current.MoveToFirstAttribute ()) {
+                                               do {
+                                                       if (key.Matches (desc.Current, value))
+                                                               AddResult (result, desc.Current);       
+                                               } while (desc.Current.MoveToNext ());
                                                
-                                               if (desc.Current.MoveToFirstAttribute ()) {
-                                                       do {
-                                                               if (key.Matches (desc.Current, value))
-                                                                       AddResult (result, desc.Current);       
-                                                       } while (desc.Current.MoveToNext ());
-                                                       
-                                                       desc.Current.MoveToParent ();
-                                               }
+                                               desc.Current.MoveToParent ();
                                        }
                                }
                        }