2003-04-25 Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
[mono.git] / mcs / class / System.XML / System.Xml / XmlWriter.cs
1 //
2 // System.Xml.XmlTextWriter
3 //
4 // Author:
5 //   Kral Ferch <kral_ferch@hotmail.com>
6 //
7 // (C) 2002 Kral Ferch
8 //
9
10 using System;
11
12 namespace System.Xml
13 {
14         public abstract class XmlWriter
15         {
16                 #region Fields
17
18                 protected WriteState ws = WriteState.Start;
19                 protected XmlNamespaceManager namespaceManager = new XmlNamespaceManager (new NameTable ());
20
21                 #endregion
22
23                 #region Constructors
24
25                 protected XmlWriter () { }
26
27                 #endregion
28
29                 #region Properties
30
31                 public abstract WriteState WriteState { get; }
32                 
33                 public abstract string XmlLang { get; }
34
35                 public abstract XmlSpace XmlSpace { get; }
36
37                 #endregion
38
39                 #region Methods
40
41                 public abstract void Close ();
42
43                 public abstract void Flush ();
44
45                 public abstract string LookupPrefix (string ns);
46
47                 [MonoTODO("DTDs must be implemented to use 'defattr' parameter.")]
48                 public virtual void WriteAttributes (XmlReader reader, bool defattr)
49                 {
50                         if(reader == null)
51                                 throw new ArgumentException("null XmlReader specified.", "reader");
52
53                         switch (reader.NodeType) {
54                         case XmlNodeType.XmlDeclaration:
55                                 string val = reader ["version"];
56                                 if (val != String.Empty)
57                                         WriteAttributeString ("version", val);
58                                 val = reader ["encoding"];
59                                 if (val != String.Empty)
60                                         WriteAttributeString ("encoding", val);
61                                 val = reader ["standalone"];
62                                 if(val != String.Empty)
63                                         WriteAttributeString ("standalone", val);
64                                 break;
65                         case XmlNodeType.Element:
66                                 if (reader.MoveToFirstAttribute ())
67                                         goto case XmlNodeType.Attribute;
68                                 break;
69                         case XmlNodeType.Attribute:
70                                 do {
71                                         // FIXME: use ReadAttributeValue () for strictly write EntityReference.
72                                         WriteAttributeString (reader.Prefix, reader.LocalName, reader.NamespaceURI, reader.Value);
73                                 } while (reader.MoveToNextAttribute ());
74                                 break;
75                         default:
76                                 throw new XmlException("NodeType is not one of Element, Attribute, nor XmlDeclaration.");
77                         }
78                 }
79
80                 public void WriteAttributeString (string localName, string value)
81                 {
82                         WriteAttributeString ("", localName, "", value);
83                 }
84
85                 public void WriteAttributeString (string localName, string ns, string value)
86                 {
87                         WriteAttributeString ("", localName, ns, value);
88                 }
89
90                 public void WriteAttributeString (string prefix, string localName, string ns, string value)
91                 {
92                         if ((prefix == "xmlns") || (localName == "xmlns"))
93                           {
94                                 ns = value;
95                                 
96                                 if (prefix == "xmlns" && namespaceManager.HasNamespace (localName))
97                                         return;
98                                 
99                                 /* Users need to be able to re-declare the default namespace for subnodes
100                                 else if (localName == "xmlns" && namespaceManager.HasNamespace (String.Empty))
101                                         return;
102                                 */
103                           }
104                         
105                         WriteStartAttribute (prefix, localName, ns);
106                         WriteString (value);
107                         WriteEndAttribute ();
108
109                         if ((prefix == "xmlns") || (localName == "xmlns")) 
110                         {
111                                 if (prefix == "xmlns")
112                                         namespaceManager.AddNamespace (localName, ns);
113                                 else
114                                         namespaceManager.AddNamespace ("", ns);
115                         }
116                         
117                 }
118
119                 public abstract void WriteBase64 (byte[] buffer, int index, int count);
120
121                 public abstract void WriteBinHex (byte[] buffer, int index, int count);
122
123                 public abstract void WriteCData (string text);
124
125                 public abstract void WriteCharEntity (char ch);
126
127                 public abstract void WriteChars (char[] buffer, int index, int count);
128
129                 public abstract void WriteComment (string text);
130
131                 public abstract void WriteDocType (string name, string pubid, string sysid, string subset);
132
133                 public void WriteElementString (string localName, string value)
134                 {
135                         WriteStartElement(localName);
136                         WriteString(value);
137                         WriteEndElement();
138                 }
139
140                 public void WriteElementString (string localName, string ns, string value)
141                 {
142                         WriteStartElement(localName, ns);
143                         WriteString(value);
144                         WriteEndElement();
145                 }
146
147                 public abstract void WriteEndAttribute ();
148
149                 public abstract void WriteEndDocument ();
150
151                 public abstract void WriteEndElement ();
152
153                 public abstract void WriteEntityRef (string name);
154
155                 public abstract void WriteFullEndElement ();
156
157                 public abstract void WriteName (string name);
158
159                 public abstract void WriteNmToken (string name);
160
161                 [MonoTODO("needs to test")]
162                 public virtual void WriteNode (XmlReader reader, bool defattr)
163                 {
164                         if (reader == null)
165                                 throw new ArgumentException ();
166
167                         if (reader.ReadState == ReadState.Initial) {
168                                 reader.Read ();
169                                 do {
170                                         WriteNode (reader, defattr);
171                                 } while (!reader.EOF);
172                                 return;
173                         }
174
175                         switch (reader.NodeType) {
176                         case XmlNodeType.Element:
177                                 WriteStartElement (reader.Prefix, reader.LocalName, reader.NamespaceURI);
178                                 WriteAttributes (reader, defattr);
179                                 reader.MoveToElement ();
180                                 if (reader.IsEmptyElement)
181                                         WriteEndElement ();
182                                 else {
183                                         int depth = reader.Depth;
184                                         reader.Read ();
185                                         do {
186                                                 WriteNode (reader, defattr);
187                                         } while (depth < reader.Depth);
188                                         WriteEndElement ();
189                                 }
190                                 break;
191                         // In case of XmlAttribute, don't proceed reader.
192                         case XmlNodeType.Attribute:
193                                 return;
194                         case XmlNodeType.Text:
195                                 WriteString (reader.Value);
196                                 break;
197                         case XmlNodeType.CDATA:
198                                 WriteCData (reader.Value);
199                                 break;
200                         case XmlNodeType.EntityReference:
201                                 WriteEntityRef (reader.Name);
202                                 break;
203                         case XmlNodeType.ProcessingInstruction:
204                                 WriteProcessingInstruction (reader.Name, reader.Value);
205                                 break;
206                         case XmlNodeType.Comment:
207                                 WriteComment (reader.Value);
208                                 break;
209                         case XmlNodeType.DocumentType:
210                                 WriteDocType (reader.Name,
211                                         reader ["PUBLIC"], reader ["SYSTEM"], reader.Value);
212                                 break;
213                         case XmlNodeType.SignificantWhitespace:
214                                 goto case XmlNodeType.Whitespace;
215                         case XmlNodeType.Whitespace:
216                                 WriteWhitespace (reader.Value);
217                                 break;
218                         case XmlNodeType.EndElement:
219                                 WriteEndElement ();
220                                 break;
221                         case XmlNodeType.EndEntity:
222                                 break;
223                         case XmlNodeType.XmlDeclaration:
224                                 string st = reader.GetAttribute ("standalone");
225                                 if (st != String.Empty)
226                                         WriteStartDocument (st.ToLower () == "yes");
227                                 else
228                                         WriteStartDocument ();
229                                 break;
230                         default:
231                                 throw new NotImplementedException ();
232                         }
233                         reader.Read ();
234                 }
235
236                 public abstract void WriteProcessingInstruction (string name, string text);
237
238                 public abstract void WriteQualifiedName (string localName, string ns);
239
240                 public abstract void WriteRaw (string data);
241
242                 public abstract void WriteRaw (char[] buffer, int index, int count);
243
244                 public void WriteStartAttribute (string localName, string ns)
245                 {
246                         WriteStartAttribute (null, localName, ns);
247                 }
248
249                 public abstract void WriteStartAttribute (string prefix, string localName, string ns);
250
251                 public abstract void WriteStartDocument ();
252
253                 public abstract void WriteStartDocument (bool standalone);
254
255                 public void WriteStartElement (string localName)
256                 {
257                         WriteStartElement (null, localName, null);
258                 }
259
260                 public void WriteStartElement (string localName, string ns)
261                 {
262                         WriteStartElement (null, localName, ns);
263                 }
264
265                 public abstract void WriteStartElement (string prefix, string localName, string ns);
266
267                 public abstract void WriteString (string text);
268
269                 public abstract void WriteSurrogateCharEntity (char lowChar, char highChar);
270
271                 public abstract void WriteWhitespace (string ws);
272
273                 #endregion
274         }
275 }