2005-03-08 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.XML / Mono.Xml.Xsl / XslOutput.cs
1 //
2 // XslOutput.cs
3 //
4 // Authors:
5 //      Ben Maurer (bmaurer@users.sourceforge.net)
6 //      Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
7 //      Oleg Tkachenko (oleg@tkachenko.com)
8 //      
9 // (C) 2003 Ben Maurer
10 // (C) 2003 Atsushi Enomoto
11 // (C) 2003 Oleg Tkachenko
12 //
13
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 // 
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 // 
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 //
34
35 using System;
36 using System.Collections;
37 using System.Xml;
38 using System.Xml.Schema;
39 using System.Xml.XPath;
40 using System.Xml.Xsl;
41 using System.Text;
42
43 namespace Mono.Xml.Xsl
44 {
45         using QName = System.Xml.XmlQualifiedName;
46
47         internal enum OutputMethod {
48                 XML,
49                 HTML,
50                 Text,
51                 Custom,
52                 Unknown
53         }
54         
55         internal enum StandaloneType {
56                 NONE,
57                 YES,
58                 NO
59         }
60         
61         internal class XslOutput        // also usable for xsl:result-document
62         {
63                 string uri;
64                 QName customMethod;
65                 OutputMethod method = OutputMethod.Unknown; 
66                 string version;
67                 Encoding encoding = System.Text.Encoding.UTF8;
68                 bool omitXmlDeclaration;
69                 StandaloneType standalone = StandaloneType.NONE;
70                 string doctypePublic;
71                 string doctypeSystem;
72                 QName [] cdataSectionElements;
73                 string indent;
74                 string mediaType;
75
76                 // for compilation only.
77                 ArrayList cdSectsList = new ArrayList ();
78
79                 public XslOutput (string uri)
80                 {
81                         this.uri = uri;
82                 }
83
84                 public OutputMethod Method { get { return method; }}
85                 public QName CustomMethod { get { return customMethod; }}
86
87                 public string Version {
88                         get { return version; }
89                 }
90
91                 public Encoding Encoding {
92                         get { return encoding; }
93                 }
94
95                 public string Uri {
96                         get { return uri; }
97                 }
98
99                 public bool OmitXmlDeclaration {
100                         get { return omitXmlDeclaration; }
101                 }
102
103                 public StandaloneType Standalone {
104                         get { return standalone; }
105                 }
106
107                 public string DoctypePublic {
108                         get { return doctypePublic; }
109                 }
110
111                 public string DoctypeSystem {
112                         get { return doctypeSystem; }
113                 }
114
115                 public QName [] CDataSectionElements {
116                         get {
117                                 if (cdataSectionElements == null)
118                                         cdataSectionElements = cdSectsList.ToArray (typeof (QName)) as QName [];
119                                 return cdataSectionElements;
120                         }
121                 }
122
123                 public string Indent {
124                         get { return indent; }
125                 }
126
127                 public string MediaType {
128                         get { return mediaType; }
129                 }
130
131                 public void Fill (XPathNavigator nav)
132                 {
133                         string att;
134                         
135                         att = nav.GetAttribute ("cdata-section-elements", "");
136                         if (att != String.Empty)
137                                 cdSectsList.AddRange (XslNameUtil.FromListString (att, nav));
138
139                         att = nav.GetAttribute ("method", "");
140
141                         if (att != String.Empty) {
142                                 switch (att) {
143                                 case "xml":
144                                         method = OutputMethod.XML;
145                                         break;
146                                 case "html":
147                                         omitXmlDeclaration = true;
148                                         method = OutputMethod.HTML;
149                                         break;
150                                 case "text":
151                                         omitXmlDeclaration = true;
152                                         method = OutputMethod.Text;
153                                         break;
154                                 default:
155                                         method = OutputMethod.Custom;
156                                         customMethod = XslNameUtil.FromString (att, nav);
157                                         if (customMethod.Namespace == String.Empty) {
158                                                 IXmlLineInfo li = nav as IXmlLineInfo;
159                                                 throw new XsltCompileException (new ArgumentException ("Invalid output method value: '" + att + 
160                                                         "'. It must be either 'xml' or 'html' or 'text' or QName."),
161                                                         nav.BaseURI,
162                                                         li != null ? li.LineNumber : 0,
163                                                         li != null ? li.LinePosition : 0);
164                                         }
165                                         break;
166                                 }
167                         }
168
169                         att = nav.GetAttribute ("version", "");
170                         if (att != String.Empty)
171                                 this.version = att;
172
173                         att = nav.GetAttribute ("encoding", "");
174                         if (att != String.Empty)
175                                 try {
176                                         this.encoding = System.Text.Encoding.GetEncoding (att);
177                                 }
178                                 catch (ArgumentException) {
179                                         // MS.NET just leaves the default encoding when encoding is unknown
180                                 }
181                                 catch (NotSupportedException) {
182                                         // Workaround for a bug in System.Text, it throws invalid exception
183                                 }
184
185                         att = nav.GetAttribute ("standalone", "");
186                         if (att != String.Empty)
187                                 //TODO: Should we validate values?                
188                                 this.standalone = att == "yes" ? StandaloneType.YES : StandaloneType.NO;
189
190
191                         att = nav.GetAttribute ("doctype-public", "");
192                         if (att != String.Empty)
193                                 this.doctypePublic = att;
194
195                         att = nav.GetAttribute ("doctype-system", "");
196                         if (att != String.Empty)
197                                 this.doctypeSystem = att;
198
199                         att = nav.GetAttribute ("media-type", "");
200                         if (att != String.Empty)
201                                 this.mediaType = att;
202
203                         att = nav.GetAttribute ("omit-xml-declaration", "");
204                         if (att != String.Empty)
205                                 this.omitXmlDeclaration = att == "yes";
206
207                         att = nav.GetAttribute ("indent", "");
208                         if (att != String.Empty)
209                                 this.indent = att;
210                 }
211         }
212
213 }