2006-02-20 Atsushi Enomoto <atsushi@ximian.com>
[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
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                 int startDepth;
96
97                 StringBuilder tmpBuilder = new StringBuilder ();
98
99                 XsAttr [] defaultAttributes = emptyAttributeArray;
100                 int currentDefaultAttribute = -1;
101                 ArrayList defaultAttributesCache = new ArrayList ();
102                 bool defaultAttributeConsumed;
103                 XmlSchemaType currentAttrType;
104
105                 // Extra for XmlSchemaValidtingReader
106                 // (not in XsdValidatingReader)
107                 XsElement element; // ... xsinfo.Element?
108
109                 #endregion
110
111                 public XmlSchemaValidatingReader (XmlReader reader,
112                         XmlReaderSettings settings)
113                 {
114                         IXmlNamespaceResolver nsResolver = reader as IXmlNamespaceResolver;
115                         if (nsResolver == null)
116                                 throw new ArgumentException ("Argument XmlReader must implement IXmlNamespaceResolver.");
117
118                         XmlSchemaSet schemas = settings.Schemas;
119                         if (schemas == null)
120                                 schemas = new XmlSchemaSet ();
121                         options = settings.ValidationFlags;
122
123                         this.reader = reader;
124                         v = new XmlSchemaValidator (
125                                 reader.NameTable,
126                                 schemas,
127                                 nsResolver,
128                                 options);
129
130                         readerLineInfo = reader as IXmlLineInfo;
131                         startDepth = reader.Depth;
132                         getter = delegate () { return Value; };
133                         xsinfo = new XmlSchemaInfo (); // transition cache
134                         v.LineInfoProvider = this;
135                         v.ValidationEventSender = reader;
136 #if !NON_MONO
137                         if (settings != null && settings.Schemas != null)
138                                 v.XmlResolver = settings.Schemas.XmlResolver;
139                         else
140                                 v.XmlResolver = new XmlUrlResolver ();
141 #else
142                         v.XmlResolver = new XmlUrlResolver ();
143 #endif
144                         v.Initialize ();
145                 }
146
147                 public ValidationEventHandler ValidationEventHandler;
148
149                 public XmlSchemaType ElementSchemaType {
150                         get {
151                                 return element != null ? element.ElementSchemaType : null;
152                         }
153                 }
154
155                 // clear default attributes, MoveTo*Attribute() transitent
156                 // fields and so on.
157                 private void ResetStateOnRead ()
158                 {
159                         currentDefaultAttribute = -1;
160                         defaultAttributeConsumed = false;
161                         currentAttrType = null;
162                         defaultAttributes = emptyAttributeArray;
163                 }
164
165                 #region Properties
166
167                 public int LineNumber {
168                         get { return readerLineInfo != null ? readerLineInfo.LineNumber : 0; }
169                 }
170
171                 public int LinePosition {
172                         get { return readerLineInfo != null ? readerLineInfo.LinePosition : 0; }
173                 }
174
175                 public XmlSchemaType SchemaType {
176                         get {
177                                 if (ReadState != ReadState.Interactive)
178                                         return null;
179
180                                 switch (NodeType) {
181                                 case XmlNodeType.Element:
182                                         if (ElementSchemaType != null)
183                                                 return ElementSchemaType;
184                                         else
185                                                 return null;//SourceReaderSchemaType;
186                                 case XmlNodeType.Attribute:
187                                         if (currentAttrType == null) {
188                                                 ComplexType ct = ElementSchemaType as ComplexType;
189                                                 if (ct != null) {
190                                                         XsAttr attdef = ct.AttributeUses [new XmlQualifiedName (LocalName, NamespaceURI)] as XsAttr;
191                                                         if (attdef != null)
192                                                                 currentAttrType = attdef.AttributeSchemaType;
193                                                         return currentAttrType;
194                                                 }
195 //                                              currentAttrType = SourceReaderSchemaType;
196                                         }
197                                         return currentAttrType;
198                                 default:
199                                         return null;//SourceReaderSchemaType;
200                                 }
201                         }
202                 }
203
204                 public ValidationType ValidationType {
205                         get { return validationType; }
206                         set {
207                                 if (ReadState != ReadState.Initial)
208                                         throw new InvalidOperationException ("ValidationType must be set before reading.");
209                                 validationType = value;
210                         }
211                 }
212
213                 public IDictionary<string, string> GetNamespacesInScope (XmlNamespaceScope scope)
214                 {
215                         IXmlNamespaceResolver resolver = reader as IXmlNamespaceResolver;
216                         if (resolver == null)
217                                 throw new NotSupportedException ("The input XmlReader does not implement IXmlNamespaceResolver and thus this validating reader cannot collect in-scope namespaces.");
218                         return resolver.GetNamespacesInScope (scope);
219                 }
220
221                 public string LookupPrefix (string ns)
222                 {
223                         return nsResolver.LookupPrefix (ns);
224                 }
225
226                 // Public Overriden Properties
227
228                 public override int AttributeCount {
229                         get {
230                                 return reader.AttributeCount + defaultAttributes.Length;
231                         }
232                 }
233
234                 public override string BaseURI {
235                         get { return reader.BaseURI; }
236                 }
237
238                 // If this class is used to implement XmlValidatingReader,
239                 // it should be left to DTDValidatingReader. In other cases,
240                 // it depends on the reader's ability.
241                 public override bool CanResolveEntity {
242                         get { return reader.CanResolveEntity; }
243                 }
244
245                 public override int Depth {
246                         get {
247                                 if (currentDefaultAttribute < 0)
248                                         return reader.Depth;
249                                 if (this.defaultAttributeConsumed)
250                                         return reader.Depth + 2;
251                                 return reader.Depth + 1;
252                         }
253                 }
254
255                 public override bool EOF {
256                         get { return reader.EOF; }
257                 }
258
259                 public override bool HasValue {
260                         get {
261                                 if (currentDefaultAttribute < 0)
262                                         return reader.HasValue;
263                                 return true;
264                         }
265                 }
266
267                 public override bool IsDefault {
268                         get {
269                                 if (currentDefaultAttribute < 0)
270                                         return reader.IsDefault;
271                                 return true;
272                         }
273                 }
274
275                 public override bool IsEmptyElement {
276                         get {
277                                 if (currentDefaultAttribute < 0)
278                                         return reader.IsEmptyElement;
279                                 return false;
280                         }
281                 }
282
283                 public override string this [int i] {
284                         get { return GetAttribute (i); }
285                 }
286
287                 public override string this [string name] {
288                         get { return GetAttribute (name); }
289                 }
290
291                 public override string this [string localName, string ns] {
292                         get { return GetAttribute (localName, ns); }
293                 }
294
295                 int IXmlLineInfo.LineNumber {
296                         get { return readerLineInfo != null ? readerLineInfo.LineNumber : 0; }
297                 }
298
299                 int IXmlLineInfo.LinePosition {
300                         get { return readerLineInfo != null ? readerLineInfo.LinePosition : 0; }
301                 }
302
303                 public override string LocalName {
304                         get {
305                                 if (currentDefaultAttribute < 0)
306                                         return reader.LocalName;
307                                 if (defaultAttributeConsumed)
308                                         return String.Empty;
309                                 return defaultAttributes [currentDefaultAttribute].QualifiedName.Name;
310                         }
311                 }
312
313                 public override string Name {
314                         get {
315                                 if (currentDefaultAttribute < 0)
316                                         return reader.Name;
317                                 if (defaultAttributeConsumed)
318                                         return String.Empty;
319
320                                 XmlQualifiedName qname = defaultAttributes [currentDefaultAttribute].QualifiedName;
321                                 string prefix = Prefix;
322                                 if (prefix == String.Empty)
323                                         return qname.Name;
324                                 else
325                                         return String.Concat (prefix, ":", qname.Name);
326                         }
327                 }
328
329                 public override string NamespaceURI {
330                         get {
331                                 if (currentDefaultAttribute < 0)
332                                         return reader.NamespaceURI;
333                                 if (defaultAttributeConsumed)
334                                         return String.Empty;
335                                 return defaultAttributes [currentDefaultAttribute].QualifiedName.Namespace;
336                         }
337                 }
338
339                 public override XmlNameTable NameTable {
340                         get { return reader.NameTable; }
341                 }
342
343                 public override XmlNodeType NodeType {
344                         get {
345                                 if (currentDefaultAttribute < 0)
346                                         return reader.NodeType;
347                                 if (defaultAttributeConsumed)
348                                         return XmlNodeType.Text;
349                                 return XmlNodeType.Attribute;
350                         }
351                 }
352
353 #if !NON_MONO
354                 public XmlParserContext ParserContext {
355                         get { return XmlSchemaUtil.GetParserContext (reader); }
356                 }
357 #endif
358
359                 public override string Prefix {
360                         get {
361                                 if (currentDefaultAttribute < 0)
362                                         return reader.Prefix;
363                                 if (defaultAttributeConsumed)
364                                         return String.Empty;
365                                 XmlQualifiedName qname = defaultAttributes [currentDefaultAttribute].QualifiedName;
366                                 string prefix = nsResolver.LookupPrefix (qname.Namespace);
367                                 if (prefix == null)
368                                         return String.Empty;
369                                 else
370                                         return prefix;
371                         }
372                 }
373
374                 public override char QuoteChar {
375                         get { return reader.QuoteChar; }
376                 }
377
378                 public override ReadState ReadState {
379                         get { return reader.ReadState; }
380                 }
381
382                 public override IXmlSchemaInfo SchemaInfo {
383                         get { return this; }
384                 }
385
386                 public override string Value {
387                         get {
388                                 if (currentDefaultAttribute < 0)
389                                         return reader.Value;
390                                 string value = defaultAttributes [currentDefaultAttribute].ValidatedDefaultValue;
391                                 if (value == null)
392                                         value = defaultAttributes [currentDefaultAttribute].ValidatedFixedValue;
393                                 return value;
394                         }
395                 }
396
397                 public override string XmlLang {
398                         get {
399                                 string xmlLang = reader.XmlLang;
400                                 if (xmlLang != null)
401                                         return xmlLang;
402                                 int idx = this.FindDefaultAttribute ("lang", XmlNamespaceManager.XmlnsXml);
403                                 if (idx < 0)
404                                         return null;
405                                 xmlLang = defaultAttributes [idx].ValidatedDefaultValue;
406                                 if (xmlLang == null)
407                                         xmlLang = defaultAttributes [idx].ValidatedFixedValue;
408                                 return xmlLang;
409                         }
410                 }
411
412                 public override XmlSpace XmlSpace {
413                         get {
414                                 XmlSpace space = reader.XmlSpace;
415                                 if (space != XmlSpace.None)
416                                         return space;
417                                 int idx = this.FindDefaultAttribute ("space", XmlNamespaceManager.XmlnsXml);
418                                 if (idx < 0)
419                                         return XmlSpace.None;
420                                 string spaceSpec = defaultAttributes [idx].ValidatedDefaultValue;
421                                 if (spaceSpec == null)
422                                         spaceSpec = defaultAttributes [idx].ValidatedFixedValue;
423                                 return (XmlSpace) Enum.Parse (typeof (XmlSpace), spaceSpec, false);
424                         }
425                 }
426                 #endregion
427
428                 #region Public Methods
429
430                 // Overrided Methods
431
432                 public override void Close ()
433                 {
434                         reader.Close ();
435                 }
436
437                 public override string GetAttribute (int i)
438                 {
439                         switch (reader.NodeType) {
440                         case XmlNodeType.XmlDeclaration:
441                         case XmlNodeType.DocumentType:
442                                 return reader.GetAttribute (i);
443                         }
444
445                         if (reader.AttributeCount > i)
446                                 reader.GetAttribute (i);
447                         int defIdx = i - reader.AttributeCount;
448                         if (i < AttributeCount)
449                                 return defaultAttributes [defIdx].DefaultValue;
450
451                         throw new ArgumentOutOfRangeException ("i", i, "Specified attribute index is out of range.");
452                 }
453
454                 public override string GetAttribute (string name)
455                 {
456                         switch (reader.NodeType) {
457                         case XmlNodeType.XmlDeclaration:
458                         case XmlNodeType.DocumentType:
459                                 return reader.GetAttribute (name);
460                         }
461
462                         string value = reader.GetAttribute (name);
463                         if (value != null)
464                                 return value;
465
466                         XmlQualifiedName qname = SplitQName (name);
467                         return GetDefaultAttribute (qname.Name, qname.Namespace);
468                 }
469
470                 private XmlQualifiedName SplitQName (string name)
471                 {
472                         XmlConvert.VerifyName (name);
473
474                         Exception ex = null;
475                         XmlQualifiedName qname = XmlSchemaUtil.ToQName (reader, name, out ex);
476                         if (ex != null)
477                                 return XmlQualifiedName.Empty;
478                         else
479                                 return qname;
480                 }
481
482                 public override string GetAttribute (string localName, string ns)
483                 {
484                         switch (reader.NodeType) {
485                         case XmlNodeType.XmlDeclaration:
486                         case XmlNodeType.DocumentType:
487                                 return reader.GetAttribute (localName, ns);
488                         }
489
490                         string value = reader.GetAttribute (localName, ns);
491                         if (value != null)
492                                 return value;
493
494                         return GetDefaultAttribute (localName, ns);
495                 }
496
497                 private string GetDefaultAttribute (string localName, string ns)
498                 {
499                         int idx = this.FindDefaultAttribute (localName, ns);
500                         if (idx < 0)
501                                 return null;
502                         string value = defaultAttributes [idx].ValidatedDefaultValue;
503                         if (value == null)
504                                 value = defaultAttributes [idx].ValidatedFixedValue;
505                         return value;
506                 }
507
508                 private int FindDefaultAttribute (string localName, string ns)
509                 {
510                         for (int i = 0; i < this.defaultAttributes.Length; i++) {
511                                 XsAttr attr = defaultAttributes [i];
512                                 if (attr.QualifiedName.Name == localName &&
513                                         (ns == null || attr.QualifiedName.Namespace == ns))
514                                         return i;
515                         }
516                         return -1;
517                 }
518
519                 bool IXmlLineInfo.HasLineInfo ()
520                 {
521                         return readerLineInfo != null && readerLineInfo.HasLineInfo ();
522                 }
523
524                 public override string LookupNamespace (string prefix)
525                 {
526                         return reader.LookupNamespace (prefix);
527                 }
528
529                 public override void MoveToAttribute (int i)
530                 {
531                         switch (reader.NodeType) {
532                         case XmlNodeType.XmlDeclaration:
533                         case XmlNodeType.DocumentType:
534                                 reader.MoveToAttribute (i);
535                                 return;
536                         }
537
538                         currentAttrType = null;
539                         if (i < reader.AttributeCount) {
540                                 reader.MoveToAttribute (i);
541                                 this.currentDefaultAttribute = -1;
542                                 this.defaultAttributeConsumed = false;
543                         }
544
545                         if (i < AttributeCount) {
546                                 this.currentDefaultAttribute = i - reader.AttributeCount;
547                                 this.defaultAttributeConsumed = false;
548                         }
549                         else
550                                 throw new ArgumentOutOfRangeException ("i", i, "Attribute index is out of range.");
551                 }
552
553                 public override bool MoveToAttribute (string name)
554                 {
555                         switch (reader.NodeType) {
556                         case XmlNodeType.XmlDeclaration:
557                         case XmlNodeType.DocumentType:
558                                 return reader.MoveToAttribute (name);
559                         }
560
561                         currentAttrType = null;
562                         bool b = reader.MoveToAttribute (name);
563                         if (b) {
564                                 this.currentDefaultAttribute = -1;
565                                 this.defaultAttributeConsumed = false;
566                                 return true;
567                         }
568
569                         return MoveToDefaultAttribute (name, null);
570                 }
571
572                 public override bool MoveToAttribute (string localName, string ns)
573                 {
574                         switch (reader.NodeType) {
575                         case XmlNodeType.XmlDeclaration:
576                         case XmlNodeType.DocumentType:
577                                 return reader.MoveToAttribute (localName, ns);
578                         }
579
580                         currentAttrType = null;
581                         bool b = reader.MoveToAttribute (localName, ns);
582                         if (b) {
583                                 this.currentDefaultAttribute = -1;
584                                 this.defaultAttributeConsumed = false;
585                                 return true;
586                         }
587
588                         return MoveToDefaultAttribute (localName, ns);
589                 }
590
591                 private bool MoveToDefaultAttribute (string localName, string ns)
592                 {
593                         int idx = this.FindDefaultAttribute (localName, ns);
594                         if (idx < 0)
595                                 return false;
596                         currentDefaultAttribute = idx;
597                         defaultAttributeConsumed = false;
598                         return true;
599                 }
600
601                 public override bool MoveToElement ()
602                 {
603                         currentDefaultAttribute = -1;
604                         defaultAttributeConsumed = false;
605                         currentAttrType = null;
606                         return reader.MoveToElement ();
607                 }
608
609                 public override bool MoveToFirstAttribute ()
610                 {
611                         switch (reader.NodeType) {
612                         case XmlNodeType.XmlDeclaration:
613                         case XmlNodeType.DocumentType:
614                                 return reader.MoveToFirstAttribute ();
615                         }
616
617                         currentAttrType = null;
618                         if (reader.AttributeCount > 0) {
619                                 bool b = reader.MoveToFirstAttribute ();
620                                 if (b) {
621                                         currentDefaultAttribute = -1;
622                                         defaultAttributeConsumed = false;
623                                 }
624                                 return b;
625                         }
626
627                         if (this.defaultAttributes.Length > 0) {
628                                 currentDefaultAttribute = 0;
629                                 defaultAttributeConsumed = false;
630                                 return true;
631                         }
632                         else
633                                 return false;
634                 }
635
636                 public override bool MoveToNextAttribute ()
637                 {
638                         switch (reader.NodeType) {
639                         case XmlNodeType.XmlDeclaration:
640                         case XmlNodeType.DocumentType:
641                                 return reader.MoveToNextAttribute ();
642                         }
643
644                         currentAttrType = null;
645                         if (currentDefaultAttribute >= 0) {
646                                 if (defaultAttributes.Length == currentDefaultAttribute + 1)
647                                         return false;
648                                 currentDefaultAttribute++;
649                                 defaultAttributeConsumed = false;
650                                 return true;
651                         }
652
653                         bool b = reader.MoveToNextAttribute ();
654                         if (b) {
655                                 currentDefaultAttribute = -1;
656                                 defaultAttributeConsumed = false;
657                                 return true;
658                         }
659
660                         if (defaultAttributes.Length > 0) {
661                                 currentDefaultAttribute = 0;
662                                 defaultAttributeConsumed = false;
663                                 return true;
664                         }
665                         else
666                                 return false;
667                 }
668
669                 public override bool Read ()
670                 {
671                         if (!reader.Read ()) {
672                                 v.EndValidation ();
673                                 return false;
674                         }
675
676                         ResetStateOnRead ();
677
678                         switch (reader.NodeType) {
679                         case XmlNodeType.Element:
680                                 string sl = reader.GetAttribute (
681                                         "schemaLocation",
682                                         XmlSchema.InstanceNamespace);
683                                 string noNsSL = reader.GetAttribute (
684                                         "noNamespaceSchemaLocation",
685                                         XmlSchema.InstanceNamespace);
686                                 string xsiType = reader.GetAttribute ("type",
687                                         XmlSchema.InstanceNamespace);
688                                 string xsiNil = reader.GetAttribute ("nil",
689                                         XmlSchema.InstanceNamespace);
690
691                                 v.ValidateElement (reader.LocalName,
692                                         reader.NamespaceURI,
693                                         xsinfo,
694                                         xsiType,
695                                         xsiNil,
696                                         sl,
697                                         noNsSL);
698
699                                 if (reader.MoveToFirstAttribute ()) {
700                                         do {
701                                                 switch (reader.NamespaceURI) {
702                                                 case XmlSchema.InstanceNamespace:
703                                                         switch (reader.LocalName) {
704                                                         case "schemaLocation":
705                                                         case "noNamespaceSchemaLocation":
706                                                         case "nil":
707                                                         case "type":
708                                                                 continue;
709                                                         }
710                                                         break;
711                                                 case XmlNamespaceManager.XmlnsXmlns:
712                                                         continue;
713                                                 }
714                                                 v.ValidateAttribute (
715                                                         reader.LocalName,
716                                                         reader.NamespaceURI,
717                                                         getter,
718                                                         xsinfo);
719                                         } while (reader.MoveToNextAttribute ());
720                                         reader.MoveToElement ();
721                                 }
722                                 v.GetUnspecifiedDefaultAttributes (
723                                         defaultAttributesCache);
724                                 defaultAttributes = (XsAttr [])
725                                         defaultAttributesCache.ToArray (
726                                         typeof (XsAttr));
727                                 v.ValidateEndOfAttributes (xsinfo);
728                                 defaultAttributesCache.Clear ();
729
730                                 if (reader.IsEmptyElement)
731                                         goto case XmlNodeType.EndElement;
732                                 break;
733                         case XmlNodeType.EndElement:
734                                 // FIXME: find out what another overload means.
735                                 v.ValidateEndElement (xsinfo);
736                                 break;
737                         case XmlNodeType.Text:
738                                 v.ValidateText (getter);
739                                 break;
740                         case XmlNodeType.SignificantWhitespace:
741                         case XmlNodeType.Whitespace:
742                                 v.ValidateWhitespace (getter);
743                                 break;
744                         }
745
746                         return true;
747                 }
748
749                 public override bool ReadAttributeValue ()
750                 {
751                         if (currentDefaultAttribute < 0)
752                                 return reader.ReadAttributeValue ();
753
754                         if (this.defaultAttributeConsumed)
755                                 return false;
756
757                         defaultAttributeConsumed = true;
758                         return true;
759                 }
760
761 #if NET_1_0
762                 public override string ReadInnerXml ()
763                 {
764                         // MS.NET 1.0 has a serious bug here. It skips validation.
765                         return ReadInnerXmlInternal ();
766                 }
767
768                 public override string ReadOuterXml ()
769                 {
770                         // MS.NET 1.0 has a serious bug here. It skips validation.
771                         return ReadInnerXmlInternal ();
772                 }
773
774                 // XmlReader.ReadString() should call derived this.Read().
775                 public override string ReadString ()
776                 {
777                         return ReadStringInternal ();
778                 }
779 #endif
780
781                 // This class itself does not have this feature.
782                 public override void ResolveEntity ()
783                 {
784                         reader.ResolveEntity ();
785                 }
786
787                 #endregion
788
789                 #region IXmlSchemaInfo
790
791                 public bool IsNil {
792                         get { return xsinfo.IsNil; }
793                 }
794
795                 public XmlSchemaSimpleType MemberType {
796                         get { return xsinfo.MemberType; }
797                 }
798
799                 public XmlSchemaAttribute SchemaAttribute {
800                         get { return xsinfo.SchemaAttribute; }
801                 }
802
803                 public XmlSchemaElement SchemaElement {
804                         get { return xsinfo.SchemaElement; }
805                 }
806
807                 public XmlSchemaValidity Validity {
808                         get { return xsinfo.Validity; }
809                 }
810
811                 #endregion
812         }
813 }
814
815 #endif