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