2002-10-28 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / class / System.XML / System.Xml / XmlReader.cs
1 //
2 // XmlReader.cs
3 //
4 // Authors:
5 //      Jason Diamond (jason@injektilo.org)
6 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //
8 // (C) 2001, 2002 Jason Diamond  http://injektilo.org/
9 // (c) 2002 Ximian, Inc. (http://www.ximian.com)
10 //
11
12 namespace System.Xml
13 {
14         public abstract class XmlReader
15         {
16                 #region Constructor
17
18                 protected XmlReader ()
19                 {
20                 }
21
22                 #endregion
23
24                 #region Properties
25
26                 public abstract int AttributeCount { get; }
27
28                 public abstract string BaseURI { get; }
29
30                 public virtual bool CanResolveEntity
31                 {
32                         get     { return false; }
33                 }
34
35                 public abstract int Depth { get; }
36
37                 public abstract bool EOF { get; }
38
39                 public virtual bool HasAttributes
40                 {
41                         get { return AttributeCount > 0; }
42                 }
43
44                 public abstract bool HasValue { get; }
45
46                 public abstract bool IsDefault { get; }
47
48                 public abstract bool IsEmptyElement { get; }
49
50                 public abstract string this[int i] { get; }
51
52                 public abstract string this[string name] { get; }
53
54                 public abstract string this[
55                         string localName,
56                         string namespaceName]
57                 { get; }
58
59                 public abstract string LocalName { get; }
60
61                 public abstract string Name { get; }
62
63                 public abstract string NamespaceURI { get; }
64
65                 public abstract XmlNameTable NameTable { get; }
66
67                 public abstract XmlNodeType NodeType { get; }
68
69                 public abstract string Prefix { get; }
70
71                 public abstract char QuoteChar { get; }
72
73                 public abstract ReadState ReadState { get; }
74
75                 public abstract string Value { get; }
76
77                 public abstract string XmlLang { get; }
78
79                 public abstract XmlSpace XmlSpace { get; }
80
81                 #endregion
82
83                 #region Methods
84
85                 public abstract void Close ();
86
87                 public abstract string GetAttribute (int i);
88
89                 public abstract string GetAttribute (string name);
90
91                 public abstract string GetAttribute (
92                         string localName,
93                         string namespaceName);
94
95                 public static bool IsName (string s)
96                 {
97                         bool result = false;
98
99                         if (s != null && s.Length > 0) {
100                                 char[] chars = s.ToCharArray ();
101
102                                 if (XmlChar.IsFirstNameChar (chars[0])) {
103                                         int i = 1;
104                                         int n = chars.Length;
105
106                                         while (i < n && XmlChar.IsNameChar (chars[i]))
107                                                 ++i;
108
109                                         result = i == n;
110                                 }
111                         }
112
113                         return result;
114                 }
115
116                 public static bool IsNameToken (string s)
117                 {
118                         bool result = false;
119
120                         if (s != null && s.Length > 0) {
121                                 char[] chars = s.ToCharArray ();
122
123                                 int i = 0;
124                                 int n = chars.Length;
125
126                                 while (i < n && XmlChar.IsNameChar (chars[i]))
127                                         ++i;
128
129                                 result = i == n;
130                         }
131
132                         return result;
133                 }
134
135                 public virtual bool IsStartElement ()
136                 {
137                         return (MoveToContent () == XmlNodeType.Element);
138                 }
139
140                 public virtual bool IsStartElement (string name)
141                 {
142                         if (!IsStartElement ())
143                                 return false;
144
145                         return (Name == name);
146                 }
147
148                 public virtual bool IsStartElement (string localName, string namespaceName)
149                 {
150                         if (!IsStartElement ())
151                                 return false;
152
153                         return (LocalName == localName && NamespaceURI == namespaceName);
154                 }
155
156                 public abstract string LookupNamespace (string prefix);
157
158                 public abstract void MoveToAttribute (int i);
159
160                 public abstract bool MoveToAttribute (string name);
161
162                 public abstract bool MoveToAttribute (
163                         string localName,
164                         string namespaceName);
165
166                 private bool IsContent (XmlNodeType nodeType)
167                 {
168                         /* MS doc says:
169                          * (non-white space text, CDATA, Element, EndElement, EntityReference, or EndEntity)
170                          */
171                         switch (nodeType) {
172                         case XmlNodeType.Text:
173                                 return true;
174                         case XmlNodeType.CDATA:
175                                 return true;
176                         case XmlNodeType.Element:
177                                 return true;
178                         case XmlNodeType.EndElement:
179                                 return true;
180                         case XmlNodeType.EntityReference:
181                                 return true;
182                         case XmlNodeType.EndEntity:
183                                 return true;
184                         }
185
186                         return false;
187                 }
188
189                 public virtual XmlNodeType MoveToContent ()
190                 {
191                         do {
192                                 XmlNodeType nodeType = NodeType;
193                                 if (IsContent (nodeType))
194                                         return nodeType;
195                         } while (Read ());
196                         
197                         return XmlNodeType.None;
198                 }
199
200                 public abstract bool MoveToElement ();
201
202                 public abstract bool MoveToFirstAttribute ();
203
204                 public abstract bool MoveToNextAttribute ();
205
206                 public abstract bool Read ();
207
208                 public abstract bool ReadAttributeValue ();
209
210                 public virtual string ReadElementString ()
211                 {
212                         if (MoveToContent () != XmlNodeType.Element) {
213                                 string error = String.Format ("'{0}' is an invalid node type.",
214                                                               NodeType.ToString ());
215                                 throw new XmlException (this as IXmlLineInfo, error);
216                         }
217
218                         string result = String.Empty;
219                         if (!IsEmptyElement) {
220                                 Read ();
221                                 result = ReadString ();
222                                 if (NodeType != XmlNodeType.EndElement) {
223                                         string error = String.Format ("'{0}' is an invalid node type.",
224                                                                       NodeType.ToString ());
225                                         throw new XmlException (this as IXmlLineInfo, error);
226                                 }
227                         }
228
229                         Read ();
230                         return result;
231                 }
232
233                 public virtual string ReadElementString (string name)
234                 {
235                         if (MoveToContent () != XmlNodeType.Element) {
236                                 string error = String.Format ("'{0}' is an invalid node type.",
237                                                               NodeType.ToString ());
238                                 throw new XmlException (this as IXmlLineInfo, error);
239                         }
240
241                         if (name != Name) {
242                                 string error = String.Format ("The {0} tag from namespace {1} is expected.",
243                                                               Name, NamespaceURI);
244                                 throw new XmlException (this as IXmlLineInfo, error);
245                         }
246
247                         string result = String.Empty;
248                         if (!IsEmptyElement) {
249                                 Read ();
250                                 result = ReadString ();
251                                 if (NodeType != XmlNodeType.EndElement) {
252                                         string error = String.Format ("'{0}' is an invalid node type.",
253                                                                       NodeType.ToString ());
254                                         throw new XmlException (this as IXmlLineInfo, error);
255                                 }
256                         }
257
258                         Read ();
259                         return result;
260                 }
261
262                 public virtual string ReadElementString (string localName, string namespaceName)
263                 {
264                         if (MoveToContent () != XmlNodeType.Element) {
265                                 string error = String.Format ("'{0}' is an invalid node type.",
266                                                               NodeType.ToString ());
267                                 throw new XmlException (this as IXmlLineInfo, error);
268                         }
269
270                         if (localName != LocalName || NamespaceURI != namespaceName) {
271                                 string error = String.Format ("The {0} tag from namespace {1} is expected.",
272                                                               LocalName, NamespaceURI);
273                                 throw new XmlException (this as IXmlLineInfo, error);
274                         }
275
276                         string result = String.Empty;
277                         if (!IsEmptyElement) {
278                                 Read ();
279                                 result = ReadString ();
280                                 if (NodeType != XmlNodeType.EndElement) {
281                                         string error = String.Format ("'{0}' is an invalid node type.",
282                                                                       NodeType.ToString ());
283                                         throw new XmlException (this as IXmlLineInfo, error);
284                                 }
285                         }
286
287                         Read ();
288                         return result;
289                 }
290
291                 public virtual void ReadEndElement ()
292                 {
293                         if (MoveToContent () != XmlNodeType.EndElement) {
294                                 string error = String.Format ("'{0}' is an invalid node type.",
295                                                               NodeType.ToString ());
296                                 throw new XmlException (this as IXmlLineInfo, error);
297                         }
298
299                         Read ();
300                 }
301
302                 public abstract string ReadInnerXml ();
303
304                 public abstract string ReadOuterXml ();
305
306                 public virtual void ReadStartElement ()
307                 {
308                         if (MoveToContent () != XmlNodeType.Element) {
309                                 string error = String.Format ("'{0}' is an invalid node type.",
310                                                               NodeType.ToString ());
311                                 throw new XmlException (this as IXmlLineInfo, error);
312                         }
313
314                         Read ();
315                 }
316
317                 public virtual void ReadStartElement (string name)
318                 {
319                         if (MoveToContent () != XmlNodeType.Element) {
320                                 string error = String.Format ("'{0}' is an invalid node type.",
321                                                               NodeType.ToString ());
322                                 throw new XmlException (this as IXmlLineInfo, error);
323                         }
324
325                         if (name != Name) {
326                                 string error = String.Format ("The {0} tag from namespace {1} is expected.",
327                                                               Name, NamespaceURI);
328                                 throw new XmlException (this as IXmlLineInfo, error);
329                         }
330
331                         Read ();
332                 }
333
334                 public virtual void ReadStartElement (string localName, string namespaceName)
335                 {
336                         if (MoveToContent () != XmlNodeType.Element) {
337                                 string error = String.Format ("'{0}' is an invalid node type.",
338                                                               NodeType.ToString ());
339                                 throw new XmlException (this as IXmlLineInfo, error);
340                         }
341
342                         if (localName != LocalName || NamespaceURI != namespaceName) {
343                                 string error = String.Format ("The {0} tag from namespace {1} is expected.",
344                                                               LocalName, NamespaceURI);
345                                 throw new XmlException (this as IXmlLineInfo, error);
346                         }
347
348                         Read ();
349                 }
350
351                 public abstract string ReadString ();
352
353                 public abstract void ResolveEntity ();
354
355                 public virtual void Skip ()
356                 {
357                         if (ReadState != ReadState.Interactive)
358                                 return;
359
360                         MoveToElement ();
361                         if (NodeType != XmlNodeType.Element || IsEmptyElement) {
362                                 Read ();
363                                 return;
364                         }
365                                 
366                         int depth = Depth;
367                         while (Read() && depth < Depth);
368                         if (NodeType == XmlNodeType.EndElement)
369                                 Read ();
370                 }
371
372                 #endregion
373         }
374 }