46e97be596089c2974a2bda1dcd9f41bbbd232cf
[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 (XmlConstructs.IsNameStart (chars[0])) {
103                                         int i = 1;
104                                         int n = chars.Length;
105
106                                         while (i < n && XmlConstructs.IsName (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 && XmlConstructs.IsName (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                         bool loop = true;
192                         do {
193                                 switch (NodeType) {
194                                 case XmlNodeType.XmlDeclaration:
195                                 case XmlNodeType.DocumentType:
196                                 case XmlNodeType.ProcessingInstruction:
197                                 case XmlNodeType.Comment:
198                                 case XmlNodeType.Whitespace:
199                                 case XmlNodeType.SignificantWhitespace:
200                                         Read ();
201                                         break;
202                                 default:
203                                         loop = false;
204                                         break;
205                                 }
206                         } while (!EOF && loop);
207                         return XmlNodeType.None;
208                 }
209
210                 public abstract bool MoveToElement ();
211
212                 public abstract bool MoveToFirstAttribute ();
213
214                 public abstract bool MoveToNextAttribute ();
215
216                 public abstract bool Read ();
217
218                 public abstract bool ReadAttributeValue ();
219
220                 public virtual string ReadElementString ()
221                 {
222                         if (MoveToContent () != XmlNodeType.Element) {
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                         string result = String.Empty;
229                         if (!IsEmptyElement) {
230                                 Read ();
231                                 result = ReadString ();
232                                 if (NodeType != XmlNodeType.EndElement) {
233                                         string error = String.Format ("'{0}' is an invalid node type.",
234                                                                       NodeType.ToString ());
235                                         throw new XmlException (this as IXmlLineInfo, error);
236                                 }
237                         }
238
239                         Read ();
240                         return result;
241                 }
242
243                 public virtual string ReadElementString (string name)
244                 {
245                         if (MoveToContent () != XmlNodeType.Element) {
246                                 string error = String.Format ("'{0}' is an invalid node type.",
247                                                               NodeType.ToString ());
248                                 throw new XmlException (this as IXmlLineInfo, error);
249                         }
250
251                         if (name != Name) {
252                                 string error = String.Format ("The {0} tag from namespace {1} is expected.",
253                                                               Name, NamespaceURI);
254                                 throw new XmlException (this as IXmlLineInfo, error);
255                         }
256
257                         string result = String.Empty;
258                         if (!IsEmptyElement) {
259                                 Read ();
260                                 result = ReadString ();
261                                 if (NodeType != XmlNodeType.EndElement) {
262                                         string error = String.Format ("'{0}' is an invalid node type.",
263                                                                       NodeType.ToString ());
264                                         throw new XmlException (this as IXmlLineInfo, error);
265                                 }
266                         }
267
268                         Read ();
269                         return result;
270                 }
271
272                 public virtual string ReadElementString (string localName, string namespaceName)
273                 {
274                         if (MoveToContent () != XmlNodeType.Element) {
275                                 string error = String.Format ("'{0}' is an invalid node type.",
276                                                               NodeType.ToString ());
277                                 throw new XmlException (this as IXmlLineInfo, error);
278                         }
279
280                         if (localName != LocalName || NamespaceURI != namespaceName) {
281                                 string error = String.Format ("The {0} tag from namespace {1} is expected.",
282                                                               LocalName, NamespaceURI);
283                                 throw new XmlException (this as IXmlLineInfo, error);
284                         }
285
286                         string result = String.Empty;
287                         if (!IsEmptyElement) {
288                                 Read ();
289                                 result = ReadString ();
290                                 if (NodeType != XmlNodeType.EndElement) {
291                                         string error = String.Format ("'{0}' is an invalid node type.",
292                                                                       NodeType.ToString ());
293                                         throw new XmlException (this as IXmlLineInfo, error);
294                                 }
295                         }
296
297                         Read ();
298                         return result;
299                 }
300
301                 public virtual void ReadEndElement ()
302                 {
303                         if (MoveToContent () != XmlNodeType.EndElement) {
304                                 string error = String.Format ("'{0}' is an invalid node type.",
305                                                               NodeType.ToString ());
306                                 throw new XmlException (this as IXmlLineInfo, error);
307                         }
308
309                         Read ();
310                 }
311
312                 public abstract string ReadInnerXml ();
313
314                 public abstract string ReadOuterXml ();
315
316                 public virtual void ReadStartElement ()
317                 {
318                         if (MoveToContent () != XmlNodeType.Element) {
319                                 string error = String.Format ("'{0}' is an invalid node type.",
320                                                               NodeType.ToString ());
321                                 throw new XmlException (this as IXmlLineInfo, error);
322                         }
323
324                         Read ();
325                 }
326
327                 public virtual void ReadStartElement (string name)
328                 {
329                         if (MoveToContent () != XmlNodeType.Element) {
330                                 string error = String.Format ("'{0}' is an invalid node type.",
331                                                               NodeType.ToString ());
332                                 throw new XmlException (this as IXmlLineInfo, error);
333                         }
334
335                         if (name != Name) {
336                                 string error = String.Format ("The {0} tag from namespace {1} is expected.",
337                                                               Name, NamespaceURI);
338                                 throw new XmlException (this as IXmlLineInfo, error);
339                         }
340
341                         Read ();
342                 }
343
344                 public virtual void ReadStartElement (string localName, string namespaceName)
345                 {
346                         if (MoveToContent () != XmlNodeType.Element) {
347                                 string error = String.Format ("'{0}' is an invalid node type.",
348                                                               NodeType.ToString ());
349                                 throw new XmlException (this as IXmlLineInfo, error);
350                         }
351
352                         if (localName != LocalName || NamespaceURI != namespaceName) {
353                                 string error = String.Format ("The {0} tag from namespace {1} is expected.",
354                                                               LocalName, NamespaceURI);
355                                 throw new XmlException (this as IXmlLineInfo, error);
356                         }
357
358                         Read ();
359                 }
360
361                 public abstract string ReadString ();
362
363                 public abstract void ResolveEntity ();
364
365                 public virtual void Skip ()
366                 {
367                         if (ReadState != ReadState.Interactive)
368                                 return;
369
370                         MoveToElement ();
371                         if (NodeType != XmlNodeType.Element || IsEmptyElement) {
372                                 Read ();
373                                 return;
374                         }
375                                 
376                         int depth = Depth;
377                         while (Read() && depth < Depth);
378                         if (NodeType == XmlNodeType.EndElement)
379                                 Read ();
380                 }
381
382                 #endregion
383         }
384 }