System.Drawing: added email to icon and test file headers
[mono.git] / mcs / class / System.XML / Mono.Xml.Schema / XmlSchemaValidatingReader.cs
1 //
2 // XmlSchemaValidatingReader.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // (C)2004 Novell Inc,
8 //
9
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 using System;
31 using System.Collections;
32 using System.IO;
33 using System.Text;
34 using System.Xml;
35 using System.Xml.Schema;
36 using System.Xml.XPath;
37 #if !NON_MONO
38 using Mono.Xml;
39 #endif
40
41 #if NET_2_0
42
43 using System.Collections.Generic;
44 using QName = System.Xml.XmlQualifiedName;
45 using Form = System.Xml.Schema.XmlSchemaForm;
46 using Use = System.Xml.Schema.XmlSchemaUse;
47 using ContentType = System.Xml.Schema.XmlSchemaContentType;
48 using Validity = System.Xml.Schema.XmlSchemaValidity;
49 using ValidationFlags = System.Xml.Schema.XmlSchemaValidationFlags;
50 using SOMList = System.Xml.Schema.XmlSchemaObjectCollection;
51 using SOMObject = System.Xml.Schema.XmlSchemaObject;
52 using XsElement = System.Xml.Schema.XmlSchemaElement;
53 using XsAttr = System.Xml.Schema.XmlSchemaAttribute;
54 using AttrGroup = System.Xml.Schema.XmlSchemaAttributeGroup;
55 using AttrGroupRef = System.Xml.Schema.XmlSchemaAttributeGroupRef;
56 using XsDatatype = System.Xml.Schema.XmlSchemaDatatype;
57 using SchemaType = System.Xml.Schema.XmlSchemaType;
58 using SimpleType = System.Xml.Schema.XmlSchemaSimpleType;
59 using ComplexType = System.Xml.Schema.XmlSchemaComplexType;
60 using SimpleModel = System.Xml.Schema.XmlSchemaSimpleContent;
61 using SimpleExt = System.Xml.Schema.XmlSchemaSimpleContentExtension;
62 using SimpleRst = System.Xml.Schema.XmlSchemaSimpleContentRestriction;
63 using ComplexModel = System.Xml.Schema.XmlSchemaComplexContent;
64 using ComplexExt = System.Xml.Schema.XmlSchemaComplexContentExtension;
65 using ComplexRst = System.Xml.Schema.XmlSchemaComplexContentRestriction;
66 using SimpleTypeRst = System.Xml.Schema.XmlSchemaSimpleTypeRestriction;
67 using SimpleList = System.Xml.Schema.XmlSchemaSimpleTypeList;
68 using SimpleUnion = System.Xml.Schema.XmlSchemaSimpleTypeUnion;
69 using SchemaFacet = System.Xml.Schema.XmlSchemaFacet;
70 using LengthFacet = System.Xml.Schema.XmlSchemaLengthFacet;
71 using MinLengthFacet = System.Xml.Schema.XmlSchemaMinLengthFacet;
72 using Particle = System.Xml.Schema.XmlSchemaParticle;
73 using Sequence = System.Xml.Schema.XmlSchemaSequence;
74 using Choice = System.Xml.Schema.XmlSchemaChoice;
75 using ValException = System.Xml.Schema.XmlSchemaValidationException;
76
77 namespace Mono.Xml.Schema
78 {
79         internal class XmlSchemaValidatingReader : XmlReader, IXmlLineInfo,
80                 IXmlSchemaInfo, IXmlNamespaceResolver, IHasXmlParserContext
81         {
82                 static readonly XsAttr [] emptyAttributeArray =
83                         new XsAttr [0];
84
85                 #region Instance Fields
86
87                 XmlReader reader;
88                 ValidationFlags options;
89                 XmlSchemaValidator v;
90                 XmlValueGetter getter;
91                 XmlSchemaInfo xsinfo;
92                 IXmlLineInfo readerLineInfo;
93                 ValidationType validationType;
94                 IXmlNamespaceResolver nsResolver;
95
96                 XsAttr [] defaultAttributes = emptyAttributeArray;
97                 int currentDefaultAttribute = -1;
98                 ArrayList defaultAttributesCache = new ArrayList ();
99                 bool defaultAttributeConsumed;
100                 XmlSchemaType currentAttrType;
101                 bool validationDone;
102
103                 // Extra for XmlSchemaValidtingReader
104                 // (not in XsdValidatingReader)
105                 XsElement element; // ... xsinfo.Element?
106
107                 #endregion
108
109                 public XmlSchemaValidatingReader (XmlReader reader,
110                         XmlReaderSettings settings)
111                 {
112                         IXmlNamespaceResolver nsResolver = reader as IXmlNamespaceResolver;
113                         if (nsResolver == null)
114                         //      throw new ArgumentException ("Argument XmlReader must implement IXmlNamespaceResolver.");
115                                 nsResolver = new XmlNamespaceManager (reader.NameTable);
116
117                         XmlSchemaSet schemas = settings.Schemas;
118                         if (schemas == null)
119                                 schemas = new XmlSchemaSet ();
120                         options = settings.ValidationFlags;
121
122                         this.reader = reader;
123                         v = new XmlSchemaValidator (
124                                 reader.NameTable,
125                                 schemas,
126                                 nsResolver,
127                                 options);
128                         if (reader.BaseURI != String.Empty)
129                                 v.SourceUri = new Uri (reader.BaseURI);
130
131                         readerLineInfo = reader as IXmlLineInfo;
132                         getter = delegate () {
133                                 if (v.CurrentAttributeType != null)
134                                         return v.CurrentAttributeType.ParseValue (Value, NameTable, this);
135                                 else
136                                         return Value; 
137                                 };
138                         xsinfo = new XmlSchemaInfo (); // transition cache
139                         v.LineInfoProvider = this;
140                         v.ValidationEventSender = reader;
141                         this.nsResolver = nsResolver;
142 #if !NON_MONO
143                         ValidationEventHandler += delegate (object o, ValidationEventArgs e) {
144                                 settings.OnValidationError (o, e);
145                         };
146                         if (settings != null && settings.Schemas != null)
147                                 v.XmlResolver = settings.Schemas.XmlResolver;
148                         else
149                                 v.XmlResolver = new XmlUrlResolver ();
150 #else
151                         v.XmlResolver = new XmlUrlResolver ();
152 #endif
153                         v.Initialize ();
154                 }
155
156                 public event ValidationEventHandler ValidationEventHandler {
157                         add { v.ValidationEventHandler += value; }
158                         remove { v.ValidationEventHandler -= value; }
159                 }
160
161                 public XmlSchemaType ElementSchemaType {
162                         get {
163                                 return element != null ? element.ElementSchemaType : null;
164                         }
165                 }
166
167                 // clear default attributes, MoveTo*Attribute() transitent
168                 // fields and so on.
169                 private void ResetStateOnRead ()
170                 {
171                         currentDefaultAttribute = -1;
172                         defaultAttributeConsumed = false;
173                         currentAttrType = null;
174                         defaultAttributes = emptyAttributeArray;
175                         v.CurrentAttributeType = null;
176                 }
177
178                 #region Properties
179
180                 public int LineNumber {
181                         get { return readerLineInfo != null ? readerLineInfo.LineNumber : 0; }
182                 }
183
184                 public int LinePosition {
185                         get { return readerLineInfo != null ? readerLineInfo.LinePosition : 0; }
186                 }
187
188                 public XmlSchemaType SchemaType {
189                         get {
190                                 if (ReadState != ReadState.Interactive)
191                                         return null;
192
193                                 switch (NodeType) {
194                                 case XmlNodeType.Element:
195                                         if (ElementSchemaType != null)
196                                                 return ElementSchemaType;
197                                         else
198                                                 return null;//SourceReaderSchemaType;
199                                 case XmlNodeType.Attribute:
200                                         if (currentAttrType == null) {
201                                                 ComplexType ct = ElementSchemaType as ComplexType;
202                                                 if (ct != null) {
203                                                         XsAttr attdef = ct.AttributeUses [new XmlQualifiedName (LocalName, NamespaceURI)] as XsAttr;
204                                                         if (attdef != null)
205                                                                 currentAttrType = attdef.AttributeSchemaType;
206                                                         return currentAttrType;
207                                                 }
208 //                                              currentAttrType = SourceReaderSchemaType;
209                                         }
210                                         return currentAttrType;
211                                 default:
212                                         return null;//SourceReaderSchemaType;
213                                 }
214                         }
215                 }
216
217                 public ValidationType ValidationType {
218                         get { return validationType; }
219                         set {
220                                 if (ReadState != ReadState.Initial)
221                                         throw new InvalidOperationException ("ValidationType must be set before reading.");
222                                 validationType = value;
223                         }
224                 }
225
226                 public IDictionary<string, string> GetNamespacesInScope (XmlNamespaceScope scope)
227                 {
228                         IXmlNamespaceResolver resolver = reader as IXmlNamespaceResolver;
229                         if (resolver == null)
230                                 throw new NotSupportedException ("The input XmlReader does not implement IXmlNamespaceResolver and thus this validating reader cannot collect in-scope namespaces.");
231                         return resolver.GetNamespacesInScope (scope);
232                 }
233
234                 public string LookupPrefix (string ns)
235                 {
236                         return nsResolver.LookupPrefix (ns);
237                 }
238
239                 // Public Overriden Properties
240
241                 public override int AttributeCount {
242                         get {
243                                 return reader.AttributeCount + defaultAttributes.Length;
244                         }
245                 }
246
247                 public override string BaseURI {
248                         get { return reader.BaseURI; }
249                 }
250
251                 // If this class is used to implement XmlValidatingReader,
252                 // it should be left to DTDValidatingReader. In other cases,
253                 // it depends on the reader's ability.
254                 public override bool CanResolveEntity {
255                         get { return reader.CanResolveEntity; }
256                 }
257
258                 public override int Depth {
259                         get {
260                                 if (currentDefaultAttribute < 0)
261                                         return reader.Depth;
262                                 if (this.defaultAttributeConsumed)
263                                         return reader.Depth + 2;
264                                 return reader.Depth + 1;
265                         }
266                 }
267
268                 public override bool EOF {
269                         get { return reader.EOF; }
270                 }
271
272                 public override bool HasValue {
273                         get {
274                                 if (currentDefaultAttribute < 0)
275                                         return reader.HasValue;
276                                 return true;
277                         }
278                 }
279
280                 public override bool IsDefault {
281                         get {
282                                 if (currentDefaultAttribute < 0)
283                                         return reader.IsDefault;
284                                 return true;
285                         }
286                 }
287
288                 public override bool IsEmptyElement {
289                         get {
290                                 if (currentDefaultAttribute < 0)
291                                         return reader.IsEmptyElement;
292                                 return false;
293                         }
294                 }
295
296                 public override string this [int i] {
297                         get { return GetAttribute (i); }
298                 }
299
300                 public override string this [string name] {
301                         get { return GetAttribute (name); }
302                 }
303
304                 public override string this [string localName, string ns] {
305                         get { return GetAttribute (localName, ns); }
306                 }
307
308                 int IXmlLineInfo.LineNumber {
309                         get { return readerLineInfo != null ? readerLineInfo.LineNumber : 0; }
310                 }
311
312                 int IXmlLineInfo.LinePosition {
313                         get { return readerLineInfo != null ? readerLineInfo.LinePosition : 0; }
314                 }
315
316                 public override string LocalName {
317                         get {
318                                 if (currentDefaultAttribute < 0)
319                                         return reader.LocalName;
320                                 if (defaultAttributeConsumed)
321                                         return String.Empty;
322                                 return defaultAttributes [currentDefaultAttribute].QualifiedName.Name;
323                         }
324                 }
325
326                 public override string Name {
327                         get {
328                                 if (currentDefaultAttribute < 0)
329                                         return reader.Name;
330                                 if (defaultAttributeConsumed)
331                                         return String.Empty;
332
333                                 XmlQualifiedName qname = defaultAttributes [currentDefaultAttribute].QualifiedName;
334                                 string prefix = Prefix;
335                                 if (prefix == String.Empty)
336                                         return qname.Name;
337                                 else
338                                         return String.Concat (prefix, ":", qname.Name);
339                         }
340                 }
341
342                 public override string NamespaceURI {
343                         get {
344                                 if (currentDefaultAttribute < 0)
345                                         return reader.NamespaceURI;
346                                 if (defaultAttributeConsumed)
347                                         return String.Empty;
348                                 return defaultAttributes [currentDefaultAttribute].QualifiedName.Namespace;
349                         }
350                 }
351
352                 public override XmlNameTable NameTable {
353                         get { return reader.NameTable; }
354                 }
355
356                 public override XmlNodeType NodeType {
357                         get {
358                                 if (currentDefaultAttribute < 0)
359                                         return reader.NodeType;
360                                 if (defaultAttributeConsumed)
361                                         return XmlNodeType.Text;
362                                 return XmlNodeType.Attribute;
363                         }
364                 }
365
366                 public XmlParserContext ParserContext {
367                         get { return XmlSchemaUtil.GetParserContext (reader); }
368                 }
369
370                 public override string Prefix {
371                         get {
372                                 if (currentDefaultAttribute < 0)
373                                         return reader.Prefix;
374                                 if (defaultAttributeConsumed)
375                                         return String.Empty;
376                                 XmlQualifiedName qname = defaultAttributes [currentDefaultAttribute].QualifiedName;
377                                 string prefix = nsResolver.LookupPrefix (qname.Namespace);
378                                 if (prefix == null)
379                                         return String.Empty;
380                                 else
381                                         return prefix;
382                         }
383                 }
384
385                 public override char QuoteChar {
386                         get { return reader.QuoteChar; }
387                 }
388
389                 public override ReadState ReadState {
390                         get { return reader.ReadState; }
391                 }
392
393                 public override IXmlSchemaInfo SchemaInfo {
394                         get {
395                                 return new XmlSchemaInfo () {
396                                         //ContentType = this.ContentType,
397                                         IsDefault = this.IsDefault,
398                                         IsNil = this.IsNil,
399                                         MemberType = this.MemberType,
400                                         SchemaAttribute = this.SchemaAttribute,
401                                         SchemaElement = this.SchemaElement,
402                                         SchemaType = this.SchemaType,
403                                         Validity = this.Validity
404                                         };
405                         }
406                 }
407
408                 public override string Value {
409                         get {
410                                 if (currentDefaultAttribute < 0)
411                                         return reader.Value;
412                                 string value = defaultAttributes [currentDefaultAttribute].ValidatedDefaultValue;
413                                 if (value == null)
414                                         value = defaultAttributes [currentDefaultAttribute].ValidatedFixedValue;
415                                 return value;
416                         }
417                 }
418
419                 public override string XmlLang {
420                         get {
421                                 string xmlLang = reader.XmlLang;
422                                 if (xmlLang != null)
423                                         return xmlLang;
424                                 int idx = this.FindDefaultAttribute ("lang", XmlNamespaceManager.XmlnsXml);
425                                 if (idx < 0)
426                                         return null;
427                                 xmlLang = defaultAttributes [idx].ValidatedDefaultValue;
428                                 if (xmlLang == null)
429                                         xmlLang = defaultAttributes [idx].ValidatedFixedValue;
430                                 return xmlLang;
431                         }
432                 }
433
434                 public override XmlSpace XmlSpace {
435                         get {
436                                 XmlSpace space = reader.XmlSpace;
437                                 if (space != XmlSpace.None)
438                                         return space;
439                                 int idx = this.FindDefaultAttribute ("space", XmlNamespaceManager.XmlnsXml);
440                                 if (idx < 0)
441                                         return XmlSpace.None;
442                                 string spaceSpec = defaultAttributes [idx].ValidatedDefaultValue;
443                                 if (spaceSpec == null)
444                                         spaceSpec = defaultAttributes [idx].ValidatedFixedValue;
445                                 return (XmlSpace) Enum.Parse (typeof (XmlSpace), spaceSpec, false);
446                         }
447                 }
448                 #endregion
449
450                 #region Public Methods
451
452                 // Overrided Methods
453
454                 public override void Close ()
455                 {
456                         reader.Close ();
457                 }
458
459                 public override string GetAttribute (int i)
460                 {
461                         switch (reader.NodeType) {
462                         case XmlNodeType.XmlDeclaration:
463                         case XmlNodeType.DocumentType:
464                                 return reader.GetAttribute (i);
465                         }
466
467                         if (reader.AttributeCount > i)
468                                 reader.GetAttribute (i);
469                         int defIdx = i - reader.AttributeCount;
470                         if (i < AttributeCount)
471                                 return defaultAttributes [defIdx].DefaultValue;
472
473                         throw new ArgumentOutOfRangeException ("i", i, "Specified attribute index is out of range.");
474                 }
475
476                 public override string GetAttribute (string name)
477                 {
478                         switch (reader.NodeType) {
479                         case XmlNodeType.XmlDeclaration:
480                         case XmlNodeType.DocumentType:
481                                 return reader.GetAttribute (name);
482                         }
483
484                         string value = reader.GetAttribute (name);
485                         if (value != null)
486                                 return value;
487
488                         XmlQualifiedName qname = SplitQName (name);
489                         return GetDefaultAttribute (qname.Name, qname.Namespace);
490                 }
491
492                 private XmlQualifiedName SplitQName (string name)
493                 {
494                         XmlConvert.VerifyName (name);
495
496                         Exception ex = null;
497                         XmlQualifiedName qname = XmlSchemaUtil.ToQName (reader, name, out ex);
498                         if (ex != null)
499                                 return XmlQualifiedName.Empty;
500                         else
501                                 return qname;
502                 }
503
504                 public override string GetAttribute (string localName, string ns)
505                 {
506                         switch (reader.NodeType) {
507                         case XmlNodeType.XmlDeclaration:
508                         case XmlNodeType.DocumentType:
509                                 return reader.GetAttribute (localName, ns);
510                         }
511
512                         string value = reader.GetAttribute (localName, ns);
513                         if (value != null)
514                                 return value;
515
516                         return GetDefaultAttribute (localName, ns);
517                 }
518
519                 private string GetDefaultAttribute (string localName, string ns)
520                 {
521                         int idx = this.FindDefaultAttribute (localName, ns);
522                         if (idx < 0)
523                                 return null;
524                         string value = defaultAttributes [idx].ValidatedDefaultValue;
525                         if (value == null)
526                                 value = defaultAttributes [idx].ValidatedFixedValue;
527                         return value;
528                 }
529
530                 private int FindDefaultAttribute (string localName, string ns)
531                 {
532                         for (int i = 0; i < this.defaultAttributes.Length; i++) {
533                                 XsAttr attr = defaultAttributes [i];
534                                 if (attr.QualifiedName.Name == localName &&
535                                         (ns == null || attr.QualifiedName.Namespace == ns))
536                                         return i;
537                         }
538                         return -1;
539                 }
540
541                 bool IXmlLineInfo.HasLineInfo ()
542                 {
543                         return readerLineInfo != null && readerLineInfo.HasLineInfo ();
544                 }
545
546                 public override string LookupNamespace (string prefix)
547                 {
548                         return reader.LookupNamespace (prefix);
549                 }
550
551                 public override void MoveToAttribute (int i)
552                 {
553                         switch (reader.NodeType) {
554                         case XmlNodeType.XmlDeclaration:
555                         case XmlNodeType.DocumentType:
556                                 reader.MoveToAttribute (i);
557                                 return;
558                         }
559
560                         currentAttrType = null;
561                         if (i < reader.AttributeCount) {
562                                 reader.MoveToAttribute (i);
563                                 this.currentDefaultAttribute = -1;
564                                 this.defaultAttributeConsumed = false;
565                         }
566
567                         if (i < AttributeCount) {
568                                 this.currentDefaultAttribute = i - reader.AttributeCount;
569                                 this.defaultAttributeConsumed = false;
570                         }
571                         else
572                                 throw new ArgumentOutOfRangeException ("i", i, "Attribute index is out of range.");
573                 }
574
575                 public override bool MoveToAttribute (string name)
576                 {
577                         switch (reader.NodeType) {
578                         case XmlNodeType.XmlDeclaration:
579                         case XmlNodeType.DocumentType:
580                                 return reader.MoveToAttribute (name);
581                         }
582
583                         currentAttrType = null;
584                         bool b = reader.MoveToAttribute (name);
585                         if (b) {
586                                 this.currentDefaultAttribute = -1;
587                                 this.defaultAttributeConsumed = false;
588                                 return true;
589                         }
590
591                         return MoveToDefaultAttribute (name, null);
592                 }
593
594                 public override bool MoveToAttribute (string localName, string ns)
595                 {
596                         switch (reader.NodeType) {
597                         case XmlNodeType.XmlDeclaration:
598                         case XmlNodeType.DocumentType:
599                                 return reader.MoveToAttribute (localName, ns);
600                         }
601
602                         currentAttrType = null;
603                         bool b = reader.MoveToAttribute (localName, ns);
604                         if (b) {
605                                 this.currentDefaultAttribute = -1;
606                                 this.defaultAttributeConsumed = false;
607                                 return true;
608                         }
609
610                         return MoveToDefaultAttribute (localName, ns);
611                 }
612
613                 private bool MoveToDefaultAttribute (string localName, string ns)
614                 {
615                         int idx = this.FindDefaultAttribute (localName, ns);
616                         if (idx < 0)
617                                 return false;
618                         currentDefaultAttribute = idx;
619                         defaultAttributeConsumed = false;
620                         return true;
621                 }
622
623                 public override bool MoveToElement ()
624                 {
625                         currentDefaultAttribute = -1;
626                         defaultAttributeConsumed = false;
627                         currentAttrType = null;
628                         return reader.MoveToElement ();
629                 }
630
631                 public override bool MoveToFirstAttribute ()
632                 {
633                         switch (reader.NodeType) {
634                         case XmlNodeType.XmlDeclaration:
635                         case XmlNodeType.DocumentType:
636                                 return reader.MoveToFirstAttribute ();
637                         }
638
639                         currentAttrType = null;
640                         if (reader.AttributeCount > 0) {
641                                 bool b = reader.MoveToFirstAttribute ();
642                                 if (b) {
643                                         currentDefaultAttribute = -1;
644                                         defaultAttributeConsumed = false;
645                                 }
646                                 return b;
647                         }
648
649                         if (this.defaultAttributes.Length > 0) {
650                                 currentDefaultAttribute = 0;
651                                 defaultAttributeConsumed = false;
652                                 return true;
653                         }
654                         else
655                                 return false;
656                 }
657
658                 public override bool MoveToNextAttribute ()
659                 {
660                         switch (reader.NodeType) {
661                         case XmlNodeType.XmlDeclaration:
662                         case XmlNodeType.DocumentType:
663                                 return reader.MoveToNextAttribute ();
664                         }
665
666                         currentAttrType = null;
667                         if (currentDefaultAttribute >= 0) {
668                                 if (defaultAttributes.Length == currentDefaultAttribute + 1)
669                                         return false;
670                                 currentDefaultAttribute++;
671                                 defaultAttributeConsumed = false;
672                                 return true;
673                         }
674
675                         bool b = reader.MoveToNextAttribute ();
676                         if (b) {
677                                 currentDefaultAttribute = -1;
678                                 defaultAttributeConsumed = false;
679                                 return true;
680                         }
681
682                         if (defaultAttributes.Length > 0) {
683                                 currentDefaultAttribute = 0;
684                                 defaultAttributeConsumed = false;
685                                 return true;
686                         }
687                         else
688                                 return false;
689                 }
690
691                 public override bool Read ()
692                 {
693                         if (!reader.Read ()) {
694                                 if (!validationDone) {
695                                         v.EndValidation ();
696                                         validationDone = true;
697                                 }
698                                 return false;
699                         }
700
701                         ResetStateOnRead ();
702
703                         switch (reader.NodeType) {
704                         case XmlNodeType.Element:
705                                 string sl = reader.GetAttribute (
706                                         "schemaLocation",
707                                         XmlSchema.InstanceNamespace);
708                                 string noNsSL = reader.GetAttribute (
709                                         "noNamespaceSchemaLocation",
710                                         XmlSchema.InstanceNamespace);
711                                 string xsiType = reader.GetAttribute ("type",
712                                         XmlSchema.InstanceNamespace);
713                                 string xsiNil = reader.GetAttribute ("nil",
714                                         XmlSchema.InstanceNamespace);
715
716                                 v.ValidateElement (reader.LocalName,
717                                         reader.NamespaceURI,
718                                         xsinfo,
719                                         xsiType,
720                                         xsiNil,
721                                         sl,
722                                         noNsSL);
723
724                                 if (reader.MoveToFirstAttribute ()) {
725                                         do {
726                                                 switch (reader.NamespaceURI) {
727                                                 case XmlSchema.InstanceNamespace:
728                                                         switch (reader.LocalName) {
729                                                         case "schemaLocation":
730                                                         case "noNamespaceSchemaLocation":
731                                                         case "nil":
732                                                         case "type":
733                                                                 continue;
734                                                         }
735                                                         break;
736                                                 case XmlNamespaceManager.XmlnsXmlns:
737                                                         continue;
738                                                 }
739                                                 v.ValidateAttribute (
740                                                         reader.LocalName,
741                                                         reader.NamespaceURI,
742                                                         getter,
743                                                         xsinfo);
744                                         } while (reader.MoveToNextAttribute ());
745                                         reader.MoveToElement ();
746                                 }
747                                 v.GetUnspecifiedDefaultAttributes (
748                                         defaultAttributesCache);
749                                 defaultAttributes = (XsAttr [])
750                                         defaultAttributesCache.ToArray (
751                                         typeof (XsAttr));
752                                 v.ValidateEndOfAttributes (xsinfo);
753                                 defaultAttributesCache.Clear ();
754
755                                 if (reader.IsEmptyElement)
756                                         goto case XmlNodeType.EndElement;
757                                 break;
758                         case XmlNodeType.EndElement:
759                                 // FIXME: find out what another overload means.
760                                 v.ValidateEndElement (xsinfo);
761                                 break;
762                         case XmlNodeType.Text:
763                                 v.ValidateText (getter);
764                                 break;
765                         case XmlNodeType.SignificantWhitespace:
766                         case XmlNodeType.Whitespace:
767                                 v.ValidateWhitespace (getter);
768                                 break;
769                         }
770
771                         return true;
772                 }
773
774                 public override bool ReadAttributeValue ()
775                 {
776                         if (currentDefaultAttribute < 0)
777                                 return reader.ReadAttributeValue ();
778
779                         if (this.defaultAttributeConsumed)
780                                 return false;
781
782                         defaultAttributeConsumed = true;
783                         return true;
784                 }
785
786 #if NET_1_0
787                 public override string ReadInnerXml ()
788                 {
789                         // MS.NET 1.0 has a serious bug here. It skips validation.
790                         return ReadInnerXmlInternal ();
791                 }
792
793                 public override string ReadOuterXml ()
794                 {
795                         // MS.NET 1.0 has a serious bug here. It skips validation.
796                         return ReadInnerXmlInternal ();
797                 }
798
799                 // XmlReader.ReadString() should call derived this.Read().
800                 public override string ReadString ()
801                 {
802                         return ReadStringInternal ();
803                 }
804 #endif
805
806                 // This class itself does not have this feature.
807                 public override void ResolveEntity ()
808                 {
809                         reader.ResolveEntity ();
810                 }
811
812                 #endregion
813
814                 #region IXmlSchemaInfo
815
816                 public bool IsNil {
817                         get { return xsinfo.IsNil; }
818                 }
819
820                 public XmlSchemaSimpleType MemberType {
821                         get { return xsinfo.MemberType; }
822                 }
823
824                 public XmlSchemaAttribute SchemaAttribute {
825                         get { return xsinfo.SchemaAttribute; }
826                 }
827
828                 public XmlSchemaElement SchemaElement {
829                         get { return xsinfo.SchemaElement; }
830                 }
831
832                 public XmlSchemaValidity Validity {
833                         get { return xsinfo.Validity; }
834                 }
835
836                 #endregion
837         }
838 }
839
840 #endif