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