2003-08-20 Ben Maurer <bmaurer@users.sourceforge.net>
[mono.git] / mcs / class / System.XML / Mono.Xml.Xsl / XslStylesheet.cs
1 //
2 // XslStylesheet.cs
3 //
4 // Authors:
5 //      Ben Maurer (bmaurer@users.sourceforge.net)
6 //      Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
7 //      
8 // (C) 2003 Ben Maurer
9 // (C) 2003 Atsushi Enomoto
10 //
11 \r
12 using System;\r
13 using System.CodeDom;\r
14 using System.Collections;
15 using System.Collections.Specialized;\r
16 using System.Xml;\r
17 using System.Xml.Schema;\r
18 using System.Xml.XPath;\r
19 using System.Xml.Xsl;
20 using System.IO;
21
22 using Mono.Xml.Xsl.Operations;
23 \r
24 using QName = System.Xml.XmlQualifiedName;\r
25
26 namespace Mono.Xml.Xsl {\r
27 \r
28         public class XslStylesheet {\r
29                 public const string XsltNamespace = "http://www.w3.org/1999/XSL/Transform";\r
30                 public const string MSXsltNamespace = "urn:schemas-microsoft-com:xslt::script";\r
31                 
32                 Compiler c;\r
33
34                 XslStylesheet importer;\r
35                 // Top-level elements\r
36                 ArrayList imports = new ArrayList ();\r
37                 // [QName]=>XmlSpace\r
38                 Hashtable spaceControls = new Hashtable ();\r
39                 // [string stylesheet-prefix]=>string result-prefix\r
40                 Hashtable namespaceAliases = new Hashtable ();\r
41                 // [QName]=>XmlSpace\r
42                 Hashtable parameters = new Hashtable ();\r
43                 \r
44                 MSXslScriptManager msScripts = new MSXslScriptManager ();\r
45                 XslTemplateTable templates;\r
46 \r
47                 // stylesheet attributes\r
48                 string version;\r
49                 XmlQualifiedName [] extensionElementPrefixes;\r
50                 XmlQualifiedName [] excludeResultPrefixes;\r
51 \r
52                 // below are newly introduced in XSLT 2.0\r
53                 //  elements::\r
54                 // xsl:import-schema should be interpreted into it.\r
55                 XmlSchemaCollection schemas = new XmlSchemaCollection ();\r
56                 // [QName]=>XslCharacterMap\r
57                 Hashtable characterMap = new Hashtable ();\r
58                 // [QName]=>XslDateFormat\r
59                 Hashtable dateFormats = new Hashtable ();\r
60                 // [QName]=>XslFunction\r
61                 Hashtable functions = new Hashtable ();\r
62                 // [QName]=>XslSortKey\r
63                 Hashtable sortKeys = new Hashtable ();\r
64                 //  attributes::\r
65                 string xpathDefaultNamespace = "";\r
66                 XslDefaultValidation defaultValidation = XslDefaultValidation.Lax;\r
67 \r
68                 public ArrayList Imports {\r
69                         get { return imports; }\r
70                 }\r
71 \r
72                 public Hashtable SpaceControls {\r
73                         get { return spaceControls; }\r
74                 }\r
75 \r
76                 public Hashtable NamespaceAliases {\r
77                         get { return namespaceAliases; }\r
78                 }\r
79
80                 public Hashtable Parameters {\r
81                         get { return parameters; }\r
82                 }
83 \r
84                 public MSXslScriptManager ScriptManager{\r
85                         get { return msScripts; }\r
86                 }\r
87 \r
88                 public XslTemplateTable Templates {\r
89                         get { return templates; }\r
90                 }\r
91
92 \r
93                 public XslStylesheet (Compiler c)\r
94                 {
95                         this.c = c;
96                         c.PushStylesheet (this);
97                         
98                         templates = new XslTemplateTable (this);\r
99                         if (c.Input.NamespaceURI != XsltNamespace) {\r
100                                 // then it is simplified stylesheet.\r
101                                 Templates.Add (new XslTemplate (c));\r
102                         } else {\r
103                                 version = c.Input.GetAttribute ("version", "");\r
104                                 extensionElementPrefixes = c.ParseQNameListAttribute ("extension-element-prefixes");\r
105                                 excludeResultPrefixes = c.ParseQNameListAttribute ("exclude-result-prefixes");\r
106                                 
107                                 ProcessTopLevelElements ();\r
108                         }
109                         
110                         c.PopStylesheet ();\r
111                 }
112                 
113                 private XslStylesheet (Compiler c, XslStylesheet importer) : this (c)
114                 {
115                         this.importer = importer;
116                 }
117                 
118                 private void HandleInclude (string href)
119                 {
120                         c.PushInputDocument (href);
121                         ProcessTopLevelElements ();
122                         c.PopInputDocument ();
123                 }
124                 
125                 private void HandleImport (string href)
126                 {
127                         c.PushInputDocument (href);
128                         imports.Add (new XslStylesheet (c, this));
129                         c.PopInputDocument ();
130                 }
131                 
132                 private void HandleTopLevelElement ()
133                 {
134                         XPathNavigator n = c.Input;
135                         switch (n.NamespaceURI)
136                         {
137                         case XsltNamespace:
138                                 
139                                 switch (n.LocalName)
140                                 {
141                                 case "include":
142                                         HandleInclude (c.GetAttribute ("href"));
143                                         break;
144                                 case "import":
145                                         HandleImport (c.GetAttribute ("href"));
146                                         break;
147                                 case "preserve-space":
148                                         AddSpaceControls (c.ParseQNameListAttribute ("elements"), XmlSpace.Preserve, n);
149                                         break;
150                                 
151                                 case "strip-space":
152                                         AddSpaceControls (c.ParseQNameListAttribute ("elements"), XmlSpace.Default, n);
153                                         break;
154                                 
155                                 case "namespace-alias":
156                                         namespaceAliases.Add (c.GetAttribute ("stylesheet-prefix", ""), c.GetAttribute ("result-prefix", ""));
157                                         break;
158                                 
159                                 case "attribute-set":
160                                         c.AddAttributeSet (new XslAttributeSet (c));
161                                         break;
162
163                                 case "key":
164                                         c.AddKeyPattern (new XslKey (c));
165                                         break;
166                                         
167                                 case "output":
168                                         c.CompileOutput ();
169                                         break;
170                                 
171                                 case "decimal-format":
172                                         c.CompileDecimalFormat ();
173                                         break;
174                                         
175                                 case "template":
176                                         templates.Add (new XslTemplate (c));    
177                                         break;
178                                 case "variable":
179                                         c.AddGlobalVariable (new XslGlobalVariable (c));
180                                         break;
181                                 case "param":
182                                         c.AddGlobalVariable (new XslGlobalParam (c));
183                                         break;
184                                 }
185                                 break;
186                         case MSXsltNamespace:
187                                 switch (n.LocalName)
188                                 {
189                                 case "script":
190                                         msScripts.AddScript (n);
191                                         break;
192                                 }
193                                 break;
194                         }
195                 }
196                 \r
197                 private void ProcessTopLevelElements ()\r
198                 {
199                         if (c.Input.MoveToFirstChild ()) {\r
200                                 do {
201                                         if (c.Input.NodeType == XPathNodeType.Element) {                                        
202                                                 Debug.EnterNavigator (c);
203                                                 this.HandleTopLevelElement();
204                                                 Debug.ExitNavigator (c);
205                                         }
206                                 } while (c.Input.MoveToNext ());
207                                 
208                                 c.Input.MoveToParent ();
209                         }\r
210                 }\r
211 \r
212                 private void AddSpaceControls (QName [] names, XmlSpace result, XPathNavigator styleElem)\r
213                 {\r
214                         foreach (QName name in names)\r
215                                 spaceControls.Add (name, result);\r
216                 }\r
217 \r
218         }\r
219 \r
220         \r
221         public enum XslDefaultValidation\r
222         {\r
223                 Strict,\r
224                 Lax,\r
225                 Preserve,\r
226                 Strip\r
227         }\r
228 }\r