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