2 // Mono.Xml.Schema.XsdValidatingReader.cs
5 // Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
7 // (C)2003 Atsushi Enomoto
11 // This class doesn't support set_XmlResolver, since it isn't common to XmlReader interface.
12 // Try to set that of xml reader which is used to construct this object.
15 using System.Collections;
16 using System.Collections.Specialized;
19 using System.Xml.Schema;
22 namespace Mono.Xml.Schema
24 public class XsdValidatingReader : XmlReader, IXmlLineInfo, IHasXmlSchemaInfo, IHasXmlParserContext
26 static char [] wsChars = new char [] {' ', '\t', '\n', '\r'};
29 XmlValidatingReader xvReader;
30 IHasXmlSchemaInfo sourceReaderSchemaInfo;
31 IXmlLineInfo readerLineInfo;
32 bool laxElementValidation = true;
33 bool reportNoValidationError;
34 XmlSchemaCollection schemas = new XmlSchemaCollection ();
35 bool namespaces = true;
37 ArrayList idList = new ArrayList ();
38 ArrayList missingIDReferences = new ArrayList ();
41 ArrayList keyTables = new ArrayList ();
42 ArrayList currentKeyFieldConsumers = new ArrayList ();
44 XsdValidationStateManager stateManager = new XsdValidationStateManager ();
45 XsdValidationContext context = new XsdValidationContext ();
46 XsdValidationState childParticleState;
49 StringBuilder storedCharacters = new StringBuilder ();
50 bool shouldValidateCharacters;
51 int skipValidationDepth = -1;
53 XmlSchemaAttribute [] defaultAttributes = new XmlSchemaAttribute [0];
54 int currentDefaultAttribute = -1;
55 XmlQualifiedName currentQName;
57 ArrayList elementQNameStack = new ArrayList ();
61 int nonDefaultAttributeCount;
62 bool defaultAttributeConsumed;
64 // Validation engine cached object
65 ArrayList defaultAttributesCache = new ArrayList ();
66 ArrayList tmpKeyrefPool = new ArrayList ();
69 public XsdValidatingReader (XmlReader reader)
74 public XsdValidatingReader (XmlReader reader, XmlReader validatingReader)
77 xvReader = validatingReader as XmlValidatingReader;
78 if (xvReader != null) {
79 if (xvReader.ValidationType == ValidationType.None)
80 reportNoValidationError = true;
82 readerLineInfo = reader as IXmlLineInfo;
83 sourceReaderSchemaInfo = reader as IHasXmlSchemaInfo;
87 private XmlQualifiedName CurrentQName {
89 if (currentQName == null)
90 currentQName = new XmlQualifiedName (LocalName, NamespaceURI);
95 internal ArrayList CurrentKeyFieldConsumers {
96 get { return currentKeyFieldConsumers; }
99 // Public Non-overrides
101 public bool Namespaces {
102 get { return namespaces; }
103 set { namespaces = value; }
106 public XmlReader Reader {
107 get { return reader; }
110 // This should be changed before the first Read() call.
111 public XmlSchemaCollection Schemas {
112 get { return schemas; }
115 public object SchemaType {
117 if (ReadState != ReadState.Interactive)
121 case XmlNodeType.Element:
122 if (context.ActualType != null)
123 return context.ActualType;
124 else if (context.Element != null)
125 return context.Element.ElementType;
127 return SourceReaderSchemaType;
128 case XmlNodeType.Attribute:
129 // TODO: Default attribute support
130 XmlSchemaComplexType ct = context.ActualType as XmlSchemaComplexType;
132 XmlSchemaAttribute attdef = ct.AttributeUses [CurrentQName] as XmlSchemaAttribute;
134 return attdef.AttributeType;
136 return SourceReaderSchemaType;
138 return SourceReaderSchemaType;
143 private object SourceReaderSchemaType {
144 get { return this.sourceReaderSchemaInfo != null ? sourceReaderSchemaInfo.SchemaType : null; }
147 // This property is never used in Mono.
148 public ValidationType ValidationType {
150 if (reportNoValidationError)
151 return ValidationType.None;
153 return ValidationType.Schema;
157 // It is used only for independent XmlReader use, not for XmlValidatingReader.
158 public object ReadTypedValue ()
160 XmlSchemaDatatype dt = SchemaType as XmlSchemaDatatype;
161 XmlSchemaSimpleType st = SchemaType as XmlSchemaSimpleType;
168 case XmlNodeType.Element:
172 storedCharacters.Length = 0;
177 case XmlNodeType.SignificantWhitespace:
178 case XmlNodeType.Text:
179 case XmlNodeType.CDATA:
180 storedCharacters.Append (Value);
182 case XmlNodeType.Comment:
188 } while (loop && !EOF);
189 return dt.ParseValue (storedCharacters.ToString (), NameTable, ParserContext.NamespaceManager);
190 case XmlNodeType.Attribute:
191 return dt.ParseValue (Value, NameTable, ParserContext.NamespaceManager);
196 public ValidationEventHandler ValidationEventHandler;
198 // Public Overrided Properties
200 public override int AttributeCount {
203 if (NodeType == XmlNodeType.Element)
204 return attributeCount;
208 return reader.AttributeCount;
210 return nonDefaultAttributeCount + defaultAttributes.Length;
214 public override string BaseURI {
215 get { return reader.BaseURI; }
218 // If this class is used to implement XmlValidatingReader,
219 // it should be left to DTDValidatingReader. In other cases,
220 // it depends on the reader's ability.
221 public override bool CanResolveEntity {
222 get { return reader.CanResolveEntity; }
225 public override int Depth {
227 if (currentDefaultAttribute < 0)
229 if (this.defaultAttributeConsumed)
230 return reader.Depth + 2;
231 return reader.Depth + 1;
235 public override bool EOF {
236 get { return reader.EOF; }
239 public override bool HasValue {
241 if (currentDefaultAttribute < 0)
242 return reader.HasValue;
247 public override bool IsDefault {
249 if (currentDefaultAttribute < 0)
250 return reader.IsDefault;
255 public override bool IsEmptyElement {
257 if (currentDefaultAttribute < 0)
258 return reader.IsEmptyElement;
263 public override string this [int i] {
264 get { return GetAttribute (i); }
267 public override string this [string name] {
268 get { return GetAttribute (name); }
271 public override string this [string localName, string ns] {
272 get { return GetAttribute (localName, ns); }
275 int IXmlLineInfo.LineNumber {
276 get { return readerLineInfo != null ? readerLineInfo.LineNumber : 0; }
279 int IXmlLineInfo.LinePosition {
280 get { return readerLineInfo != null ? readerLineInfo.LinePosition : 0; }
283 public override string LocalName {
285 if (currentDefaultAttribute < 0)
286 return reader.LocalName;
287 if (defaultAttributeConsumed)
289 return defaultAttributes [currentDefaultAttribute].QualifiedName.Name;
293 public override string Name {
295 if (currentDefaultAttribute < 0)
297 if (defaultAttributeConsumed)
300 XmlQualifiedName qname = defaultAttributes [currentDefaultAttribute].QualifiedName;
301 string prefix = Prefix;
302 if (prefix == String.Empty)
305 return String.Concat (prefix, ":", qname.Name);
309 public override string NamespaceURI {
311 if (currentDefaultAttribute < 0)
312 return reader.NamespaceURI;
313 if (defaultAttributeConsumed)
315 return defaultAttributes [currentDefaultAttribute].QualifiedName.Namespace;
319 public override XmlNameTable NameTable {
320 get { return reader.NameTable; }
323 public override XmlNodeType NodeType {
325 if (currentDefaultAttribute < 0)
326 return reader.NodeType;
327 if (defaultAttributeConsumed)
328 return XmlNodeType.Text;
329 return XmlNodeType.Attribute;
333 public XmlParserContext ParserContext {
334 get { return XmlSchemaUtil.GetParserContext (reader); }
337 public override string Prefix {
339 if (currentDefaultAttribute < 0)
340 return reader.Prefix;
341 if (defaultAttributeConsumed)
343 XmlQualifiedName qname = defaultAttributes [currentDefaultAttribute].QualifiedName;
344 string prefix = this.ParserContext.NamespaceManager.LookupPrefix (qname.Namespace);
352 public override char QuoteChar {
353 get { return reader.QuoteChar; }
356 public override ReadState ReadState {
357 get { return reader.ReadState; }
360 public override string Value {
362 if (currentDefaultAttribute < 0)
364 return defaultAttributes [currentDefaultAttribute].ValidatedDefaultValue;
368 XmlQualifiedName qnameXmlLang = new XmlQualifiedName ("lang", XmlNamespaceManager.XmlnsXml);
370 public override string XmlLang {
372 string xmlLang = reader.XmlLang;
375 int idx = this.FindDefaultAttribute ("lang", XmlNamespaceManager.XmlnsXml);
378 return defaultAttributes [idx].ValidatedDefaultValue;
382 public override XmlSpace XmlSpace {
384 XmlSpace space = reader.XmlSpace;
385 if (space != XmlSpace.None)
387 int idx = this.FindDefaultAttribute ("space", XmlNamespaceManager.XmlnsXml);
389 return XmlSpace.None;
390 return (XmlSpace) Enum.Parse (typeof (XmlSpace), defaultAttributes [idx].ValidatedDefaultValue, false);
396 private XmlQualifiedName QualifyName (string name)
398 int colonAt = name.IndexOf (':');
400 return new XmlQualifiedName (name, null);
402 return new XmlQualifiedName (name.Substring (colonAt + 1),
403 LookupNamespace (name.Substring (0, colonAt)));
406 private void HandleError (string error)
408 HandleError (error, null);
411 private void HandleError (string error, Exception innerException)
413 if (reportNoValidationError) // extra quick check
416 XmlSchemaException schemaException = new XmlSchemaException (error,
417 this, this.BaseURI, null, innerException);
418 HandleError (schemaException);
421 private void HandleError (XmlSchemaException schemaException)
423 if (reportNoValidationError)
426 ValidationEventArgs e = new ValidationEventArgs (schemaException,
427 schemaException.Message, XmlSeverityType.Error);
429 if (this.ValidationEventHandler != null)
430 this.ValidationEventHandler (this, e);
431 else if (xvReader != null)
432 xvReader.OnValidationEvent (this, e);
435 this.xvReader.OnValidationEvent (this, e);
441 private XmlSchemaElement FindElement (string name, string ns)
443 foreach (XmlSchema target in schemas) {
444 XmlSchema matches = target.Schemas [ns];
445 if (matches != null) {
446 XmlSchemaElement result = target.Elements [new XmlQualifiedName (name, ns)] as XmlSchemaElement;
454 private XmlSchemaType FindType (XmlQualifiedName qname)
456 foreach (XmlSchema target in schemas) {
457 XmlSchemaType type = target.SchemaTypes [qname] as XmlSchemaType;
464 private void ValidateStartElementParticle ()
466 stateManager.CurrentElement = null;
467 context.ParticleState = context.ParticleState.EvaluateStartElement (reader.LocalName, reader.NamespaceURI);
468 if (context.ParticleState == XsdValidationState.Invalid)
469 HandleError ("Invalid start element: " + reader.NamespaceURI + ":" + reader.LocalName);
471 context.Element = stateManager.CurrentElement;
472 if (context.Element != null)
473 context.SchemaType = context.Element.ElementType;
476 private void ValidateEndElementParticle ()
478 if (childParticleState != null) {
479 if (!childParticleState.EvaluateEndElement ()) {
480 HandleError ("Invalid end element: " + reader.Name);
483 context.PopScope (reader.Depth);
486 // Utility for missing validation completion related to child items.
487 private void ValidateCharacters ()
489 // TODO: value context validation here.
490 if (xsiNilDepth >= 0 && xsiNilDepth < reader.Depth)
491 HandleError ("Element item appeared, while current element context is nil.");
493 storedCharacters.Append (reader.Value);
496 // Utility for missing validation completion related to child items.
497 private void ValidateEndCharacters ()
499 if (context.ActualType == null)
502 string value = storedCharacters.ToString ();
504 if (storedCharacters.Length == 0) {
505 // 3.3.4 Element Locally Valid (Element) 5.1.2
506 // TODO: check entire DefaultValid (3.3.6)
507 if (context.Element != null && context.Element.ValidatedDefaultValue != null)
508 value = context.Element.ValidatedDefaultValue;
511 XmlSchemaDatatype dt = context.ActualType as XmlSchemaDatatype;
512 XmlSchemaSimpleType st = context.ActualType as XmlSchemaSimpleType;
515 // if (st.Variety == XmlSchemaDerivationMethod.Restriction)
518 XmlSchemaComplexType ct = context.ActualType as XmlSchemaComplexType;
520 switch (ct.ContentType) {
521 case XmlSchemaContentType.ElementOnly:
522 case XmlSchemaContentType.Empty:
523 if (storedCharacters.Length > 0)
524 HandleError ("Character content not allowed.");
530 // 3.3.4 Element Locally Valid (Element) :: 5.2.2.2. Fixed value constraints
531 if (context.Element != null && context.Element.ValidatedFixedValue != null)
532 if (value != context.Element.ValidatedFixedValue)
533 HandleError ("Fixed value constraint was not satisfied.");
534 AssessStringValid (st, dt, value);
537 // Identity field value
538 while (this.currentKeyFieldConsumers.Count > 0) {
539 XsdKeyEntryField field = this.currentKeyFieldConsumers [0] as XsdKeyEntryField;
540 if (field.Identity != null)
541 HandleError ("Two or more identical field was found. Former value is '" + field.Identity + "' .");
542 object identity = null;
545 identity = dt.ParseValue (value, NameTable, ParserContext.NamespaceManager);
546 } catch (Exception ex) { // FIXME: (wishlist) This is bad manner ;-(
547 HandleError ("Identity value is invalid against its data type " + dt.TokenizedType, ex);
550 if (identity == null)
553 if (!field.SetIdentityField (identity, dt as XsdAnySimpleType, this))
554 HandleError ("Two or more identical key value was found: '" + value + "' .");
555 this.currentKeyFieldConsumers.RemoveAt (0);
558 shouldValidateCharacters = false;
561 // 3.14.4 String Valid
562 private void AssessStringValid (XmlSchemaSimpleType st,
563 XmlSchemaDatatype dt, string value)
565 XmlSchemaDatatype validatedDatatype = dt;
567 string normalized = validatedDatatype.Normalize (value);
569 XmlSchemaDatatype itemDatatype;
570 XmlSchemaSimpleType itemSimpleType;
571 switch (st.DerivedBy) {
572 case XmlSchemaDerivationMethod.List:
573 XmlSchemaSimpleTypeList listContent = st.Content as XmlSchemaSimpleTypeList;
574 values = normalized.Split (wsChars);
575 itemDatatype = listContent.ValidatedListItemType as XmlSchemaDatatype;
576 itemSimpleType = listContent.ValidatedListItemType as XmlSchemaSimpleType;
577 foreach (string each in values) {
578 if (each == String.Empty)
580 // validate against ValidatedItemType
581 if (itemDatatype != null) {
583 itemDatatype.ParseValue (each, NameTable, ParserContext.NamespaceManager);
584 } catch (Exception ex) { // FIXME: (wishlist) better exception handling ;-(
585 HandleError ("List type value contains one or more invalid values.", ex);
590 AssessStringValid (itemSimpleType, itemSimpleType.Datatype, each);
593 case XmlSchemaDerivationMethod.Union:
594 XmlSchemaSimpleTypeUnion union = st.Content as XmlSchemaSimpleTypeUnion;
596 string each = normalized;
597 // validate against ValidatedItemType
599 foreach (object eachType in union.ValidatedTypes) {
600 itemDatatype = eachType as XmlSchemaDatatype;
601 itemSimpleType = eachType as XmlSchemaSimpleType;
602 if (itemDatatype != null) {
604 itemDatatype.ParseValue (each, NameTable, ParserContext.NamespaceManager);
605 } catch (Exception) { // FIXME: (wishlist) better exception handling ;-(
611 AssessStringValid (itemSimpleType, itemSimpleType.Datatype, each);
612 } catch (XmlSchemaException) {
620 HandleError ("Union type value contains one or more invalid values.");
625 case XmlSchemaDerivationMethod.Restriction:
626 XmlSchemaSimpleTypeRestriction str = st.Content as XmlSchemaSimpleTypeRestriction;
629 /* Don't forget to validate against inherited type's facets
630 * Could we simplify this by assuming that the basetype will also
633 // mmm, will check later.
634 XmlSchemaSimpleType baseType = str.ActualBaseSchemaType as XmlSchemaSimpleType;
635 if (baseType != null) {
636 AssessStringValid(baseType, dt, normalized);
638 if (!str.ValidateValueWithFacets (normalized, NameTable)) {
639 HandleError ("Specified value was invalid against the facets.");
643 validatedDatatype = st.Datatype;
647 if (validatedDatatype != null) {
649 validatedDatatype.ParseValue (value, NameTable, ParserContext.NamespaceManager);
650 } catch (Exception ex) { // FIXME: (wishlist) It is bad manner ;-(
651 HandleError ("Invalidly typed data was specified.", ex);
656 private object GetLocalTypeDefinition (string name)
658 object xsiType = null;
659 XmlQualifiedName typeQName = QualifyName (name);
660 if (typeQName.Namespace == XmlSchema.Namespace) {
661 if (typeQName.Name == "anyType")
662 xsiType = XmlSchemaComplexType.AnyType;
664 xsiType = XmlSchemaDatatype.FromName (typeQName);
667 xsiType = FindType (typeQName);
671 // It is common to ElementLocallyValid::4 and SchemaValidityAssessment::1.2.1.2.4
672 private void AssessLocalTypeDerivationOK (object xsiType, object baseType, XmlSchemaDerivationMethod flag)
674 XmlSchemaType xsiSchemaType = xsiType as XmlSchemaType;
675 XmlSchemaComplexType baseComplexType = baseType as XmlSchemaComplexType;
676 XmlSchemaComplexType xsiComplexType = xsiSchemaType as XmlSchemaComplexType;
677 if (xsiType != baseType) {
678 // Extracted (not extraneous) check for 3.4.6 TypeDerivationOK.
679 if (baseComplexType != null)
680 flag |= baseComplexType.BlockResolved;
681 if (flag == XmlSchemaDerivationMethod.All) {
682 HandleError ("Prohibited element type substitution.");
684 } else if (xsiSchemaType != null && (flag & xsiSchemaType.DerivedBy) != 0) {
685 HandleError ("Prohibited element type substitution.");
690 if (xsiComplexType != null)
692 xsiComplexType.ValidateTypeDerivationOK (baseType, null, null);
693 } catch (XmlSchemaException ex) {
694 // HandleError ("Locally specified schema complex type derivation failed. " + ex.Message, ex);
698 XmlSchemaSimpleType xsiSimpleType = xsiType as XmlSchemaSimpleType;
699 if (xsiSimpleType != null) {
701 xsiSimpleType.ValidateTypeDerivationOK (baseType, null, null, true);
702 } catch (XmlSchemaException ex) {
703 // HandleError ("Locally specified schema simple type derivation failed. " + ex.Message, ex);
707 else if (xsiType is XmlSchemaDatatype) {
711 HandleError ("Primitive data type cannot be derived type using xsi:type specification.");
715 // Section 3.3.4 of the spec.
716 private void AssessStartElementSchemaValidity ()
718 // If the reader is inside xsi:nil (and failed on validation),
719 // then simply skip its content.
720 if (xsiNilDepth >= 0 && xsiNilDepth < reader.Depth)
721 HandleError ("Element item appeared, while current element context is nil.");
723 context.Load (reader.Depth);
724 if (childParticleState != null) {
725 context.ParticleState = childParticleState;
726 childParticleState = null;
729 // If validation state exists, then first assess particle validity.
730 if (context.ParticleState != null) {
731 ValidateStartElementParticle ();
734 string xsiNilValue = GetAttribute ("nil", XmlSchema.InstanceNamespace);
735 if (xsiNilValue != null)
736 xsiNilValue = xsiNilValue.Trim (XmlChar.WhitespaceChars);
737 bool isXsiNil = xsiNilValue == "true";
738 if (isXsiNil && this.xsiNilDepth < 0)
739 xsiNilDepth = reader.Depth;
741 // [Schema Validity Assessment (Element) 1.2]
742 // Evaluate "local type definition" from xsi:type.
743 // (See spec 3.3.4 Schema Validity Assessment (Element) 1.2.1.2.3.
744 // Note that Schema Validity Assessment(Element) 1.2 takes
745 // precedence than 1.1 of that.
747 string xsiTypeName = reader.GetAttribute ("type", XmlSchema.InstanceNamespace);
748 if (xsiTypeName != null) {
749 xsiTypeName = xsiTypeName.Trim (XmlChar.WhitespaceChars);
750 object xsiType = GetLocalTypeDefinition (xsiTypeName);
752 HandleError ("The instance type was not found: " + xsiTypeName + " .");
754 XmlSchemaType xsiSchemaType = xsiType as XmlSchemaType;
755 if (xsiSchemaType != null && this.context.Element != null) {
756 XmlSchemaType elemBaseType = context.Element.ElementType as XmlSchemaType;
757 if (elemBaseType != null && (xsiSchemaType.DerivedBy & elemBaseType.FinalResolved) != 0)
758 HandleError ("The instance type is prohibited by the type of the context element.");
759 if (elemBaseType != xsiType && (xsiSchemaType.DerivedBy & this.context.Element.BlockResolved) != 0)
760 HandleError ("The instance type is prohibited by the context element.");
762 XmlSchemaComplexType xsiComplexType = xsiType as XmlSchemaComplexType;
763 if (xsiComplexType != null && xsiComplexType.IsAbstract)
764 HandleError ("The instance type is abstract: " + xsiTypeName + " .");
766 // If current schema type exists, then this xsi:type must be
767 // valid extension of that type. See 1.2.1.2.4.
768 if (context.Element != null) {
769 // FIXME: supply *correct* base type
770 AssessLocalTypeDerivationOK (xsiType, context.Element.ElementType, context.Element.BlockResolved);
772 AssessStartElementLocallyValidType (xsiType); // 1.2.2:
773 context.LocalTypeDefinition = xsiType;
778 // Create Validation Root, if not exist.
779 // [Schema Validity Assessment (Element) 1.1]
780 if (context.Element == null)
781 context.Element = FindElement (reader.LocalName, reader.NamespaceURI);
782 if (context.Element != null) {
783 if (xsiTypeName == null) {
784 context.SchemaType = context.Element.ElementType;
785 AssessElementLocallyValidElement (context.Element, xsiNilValue); // 1.1.2
789 switch (stateManager.ProcessContents) {
790 case XmlSchemaContentProcessing.Skip:
792 case XmlSchemaContentProcessing.Lax:
794 schema = schemas [reader.NamespaceURI];
795 if (schema != null && !schema.missedSubComponents)
796 HandleError ("Element declaration for " + reader.LocalName + " is missing.");
800 schema = schemas [reader.NamespaceURI];
801 if (xsiTypeName == null && (schema == null || !schema.missedSubComponents))
802 HandleError ("Element declaration for " + reader.LocalName + " is missing.");
807 if (stateManager.ProcessContents == XmlSchemaContentProcessing.Skip)
808 skipValidationDepth = reader.Depth;
810 // Finally, create child particle state.
811 XmlSchemaComplexType xsComplexType = SchemaType as XmlSchemaComplexType;
812 if (xsComplexType != null)
813 childParticleState = stateManager.Create (xsComplexType.ContentTypeParticle);
814 else if (stateManager.ProcessContents == XmlSchemaContentProcessing.Lax)
815 childParticleState = stateManager.Create (XmlSchemaAny.AnyTypeContent);
817 childParticleState = stateManager.Create (XmlSchemaParticle.Empty);
819 AssessStartIdentityConstraints ();
821 context.PushScope (reader.Depth);
824 // 3.3.4 Element Locally Valid (Element)
825 private void AssessElementLocallyValidElement (XmlSchemaElement element, string xsiNilValue)
827 XmlQualifiedName qname = new XmlQualifiedName (reader.LocalName, reader.NamespaceURI);
830 HandleError ("Element declaration is required for " + qname);
832 if (element.actualIsAbstract)
833 HandleError ("Abstract element declaration was specified for " + qname);
835 if (!element.actualIsNillable && xsiNilValue != null)
836 HandleError ("This element declaration is not nillable: " + qname);
838 // Note that 3.2.1 xsi:nil constraints are to be validated in
839 else if (xsiNilValue == "true") {
840 // AssessElementSchemaValidity() and ValidateCharacters()
842 if (element.ValidatedFixedValue != null)
843 HandleError ("Schema instance nil was specified, where the element declaration for " + qname + "has fixed value constraints.");
846 string xsiType = reader.GetAttribute ("type", XmlSchema.InstanceNamespace);
847 if (xsiType != null) {
848 context.LocalTypeDefinition = GetLocalTypeDefinition (xsiType);
849 AssessLocalTypeDerivationOK (context.LocalTypeDefinition, element.ElementType, element.BlockResolved);
852 // 5 Not all things cannot be assessed here.
853 // It is common to 5.1 and 5.2
854 if (element.ElementType != null)
855 AssessStartElementLocallyValidType (SchemaType);
857 // 6. should be out from here.
858 // See invokation of AssessStartIdentityConstraints().
860 // 7 is going to be validated in Read() (in case of xmlreader's EOF).
863 // 3.3.4 Element Locally Valid (Type)
864 private void AssessStartElementLocallyValidType (object schemaType)
866 if (schemaType == null) { // 1.
867 HandleError ("Schema type does not exist.");
870 XmlSchemaComplexType cType = schemaType as XmlSchemaComplexType;
871 XmlSchemaSimpleType sType = schemaType as XmlSchemaSimpleType;
874 while (reader.MoveToNextAttribute ()) {
875 if (reader.NamespaceURI == XmlNamespaceManager.XmlnsXmlns)
877 if (reader.NamespaceURI != XmlSchema.InstanceNamespace)
878 HandleError ("Current simple type cannot accept attributes other than schema instance namespace.");
879 switch (reader.LocalName) {
882 case "schemaLocation":
883 case "noNamespaceSchemaLocation":
886 HandleError ("Unknown schema instance namespace attribute: " + reader.LocalName);
890 reader.MoveToElement ();
891 // 3.1.2 and 3.1.3 cannot be assessed here.
892 } else if (cType != null) {
893 if (cType.IsAbstract) { // 2.
894 HandleError ("Target complex type is abstract.");
898 AssessElementLocallyValidComplexType (cType);
902 // 3.4.4 Element Locally Valid (Complex Type)
903 // TODO ("wild IDs constraints.")
904 private void AssessElementLocallyValidComplexType (XmlSchemaComplexType cType)
907 if (cType.IsAbstract)
908 HandleError ("Target complex type is abstract.");
910 // 2 (xsi:nil and content prohibition)
911 // See AssessStartElementSchemaValidity() and ValidateCharacters()
913 string elementNs = reader.NamespaceURI;
914 // 3. attribute uses and
916 while (reader.MoveToNextAttribute ()) {
917 if (reader.NamespaceURI == "http://www.w3.org/2000/xmlns/")
919 else if (reader.NamespaceURI == XmlSchema.InstanceNamespace)
921 XmlQualifiedName qname = new XmlQualifiedName (reader.LocalName, reader.NamespaceURI);
922 object attMatch = FindAttributeDeclaration (cType, qname, elementNs);
923 if (attMatch == null)
924 HandleError ("Attribute declaration was not found for " + qname);
926 XmlSchemaAttribute attdecl = attMatch as XmlSchemaAttribute;
927 if (attdecl == null) { // i.e. anyAttribute
928 XmlSchemaAnyAttribute anyAttrMatch = attMatch as XmlSchemaAnyAttribute;
930 AssessAttributeLocallyValidUse (attdecl);
931 AssessAttributeLocallyValid (attdecl, true);
935 reader.MoveToElement ();
937 // Collect default attributes.
939 // FIXME: FixedValue check maybe extraneous.
940 foreach (XmlSchemaAttribute attr in cType.AttributeUses) {
941 if (reader [attr.QualifiedName.Name, attr.QualifiedName.Namespace] == null) {
942 if (attr.ValidatedUse == XmlSchemaUse.Required &&
943 attr.ValidatedFixedValue == null)
944 HandleError ("Required attribute " + attr.QualifiedName + " was not found.");
945 else if (attr.ValidatedDefaultValue != null)
946 defaultAttributesCache.Add (attr);
949 defaultAttributes = (XmlSchemaAttribute [])
950 defaultAttributesCache.ToArray (typeof (XmlSchemaAttribute));
951 context.DefaultAttributes = defaultAttributes;
952 defaultAttributesCache.Clear ();
953 // 5. wild IDs was already checked above.
956 // Spec 3.10.4 Item Valid (Wildcard)
957 private bool AttributeWildcardItemValid (XmlSchemaAnyAttribute anyAttr, XmlQualifiedName qname)
959 if (anyAttr.HasValueAny)
961 if (anyAttr.HasValueOther && (anyAttr.TargetNamespace == "" || reader.NamespaceURI != anyAttr.TargetNamespace))
963 if (anyAttr.HasValueTargetNamespace && reader.NamespaceURI == anyAttr.TargetNamespace)
965 if (anyAttr.HasValueLocal && reader.NamespaceURI == "")
967 foreach (string ns in anyAttr.ResolvedNamespaces)
968 if (ns == reader.NamespaceURI)
973 private XmlSchemaObject FindAttributeDeclaration (XmlSchemaComplexType cType,
974 XmlQualifiedName qname, string elementNs)
976 XmlSchemaObject result = cType.AttributeUses [qname];
979 if (cType.AttributeWildcard == null)
982 if (!AttributeWildcardItemValid (cType.AttributeWildcard, qname))
985 if (cType.AttributeWildcard.ProcessContents == XmlSchemaContentProcessing.Skip)
986 return cType.AttributeWildcard;
987 foreach (XmlSchema schema in schemas) {
988 foreach (XmlSchemaAttribute attr in schema.Attributes)
989 if (attr.QualifiedName == qname)
992 if (cType.AttributeWildcard.ProcessContents == XmlSchemaContentProcessing.Lax)
993 return cType.AttributeWildcard;
998 // 3.2.4 Attribute Locally Valid and 3.4.4 - 5.wildIDs
1000 private void AssessAttributeLocallyValid (XmlSchemaAttribute attr, bool checkWildIDs)
1003 switch (reader.NamespaceURI) {
1004 case XmlNamespaceManager.XmlnsXml:
1005 case XmlNamespaceManager.XmlnsXmlns:
1006 case XmlSchema.InstanceNamespace:
1010 if (attr.AttributeType == null)
1011 HandleError ("Attribute type is missing for " + attr.QualifiedName);
1012 XmlSchemaDatatype dt = attr.AttributeType as XmlSchemaDatatype;
1014 dt = ((XmlSchemaSimpleType) attr.AttributeType).Datatype;
1015 // It is a bit heavy process, so let's omit as long as possible ;-)
1016 if (dt != XmlSchemaSimpleType.AnySimpleType || attr.ValidatedFixedValue != null) {
1017 string normalized = dt.Normalize (reader.Value);
1018 object parsedValue = null;
1020 dt.ParseValue (normalized, reader.NameTable, this.ParserContext.NamespaceManager);
1021 } catch (Exception ex) { // FIXME: (wishlist) It is bad manner ;-(
1022 HandleError ("Attribute value is invalid against its data type " + dt.TokenizedType, ex);
1024 if (attr.ValidatedFixedValue != null && attr.ValidatedFixedValue != normalized)
1025 HandleError ("The value of the attribute " + attr.QualifiedName + " does not match with its fixed value.");
1026 // FIXME: this is extraneous checks in 3.2.4 Attribute Locally Valid.
1028 AssessEachAttributeIdentityConstraint (dt, normalized, parsedValue);
1032 private void AssessEachAttributeIdentityConstraint (XmlSchemaDatatype dt,
1033 string normalized, object parsedValue)
1035 // Get normalized value and (if required) parsedValue if missing.
1036 switch (dt.TokenizedType) {
1037 case XmlTokenizedType.IDREFS:
1038 if (normalized == null)
1039 normalized = dt.Normalize (reader.Value);
1040 if (parsedValue == null)
1041 parsedValue = dt.ParseValue (normalized, reader.NameTable, ParserContext.NamespaceManager);
1043 case XmlTokenizedType.ID:
1044 case XmlTokenizedType.IDREF:
1045 if (normalized == null)
1046 normalized = dt.Normalize (reader.Value);
1050 // Validate identity constraints.
1051 switch (dt.TokenizedType) {
1052 case XmlTokenizedType.ID:
1053 if (thisElementId != null)
1054 HandleError ("ID type attribute was already assigned in the containing element.");
1055 thisElementId = normalized;
1056 idList.Add (normalized);
1058 case XmlTokenizedType.IDREF:
1059 if (missingIDReferences.Contains (normalized))
1060 missingIDReferences.Remove (normalized);
1062 missingIDReferences.Add (normalized);
1064 case XmlTokenizedType.IDREFS:
1065 foreach (string id in (string []) parsedValue) {
1066 if (missingIDReferences.Contains (id))
1067 missingIDReferences.Remove (id);
1069 missingIDReferences.Add (id);
1076 private void AssessAttributeLocallyValidUse (XmlSchemaAttribute attr)
1078 // TODO: value constraint check
1079 // This is extra check than spec 3.5.4
1080 if (attr.ValidatedUse == XmlSchemaUse.Prohibited)
1081 HandleError ("Attribute " + attr.QualifiedName + " is prohibited in this context.");
1084 private void AssessEndElementSchemaValidity ()
1086 if (childParticleState == null)
1087 childParticleState = context.ParticleState;
1088 ValidateEndElementParticle (); // validate against childrens' state.
1090 context.Load (reader.Depth);
1092 // 3.3.4 Assess ElementLocallyValidElement 5: value constraints.
1093 // 3.3.4 Assess ElementLocallyValidType 3.1.3. = StringValid(3.14.4)
1094 // => ValidateEndCharacters().
1096 // Reset Identity constraints.
1097 for (int i = 0; i < keyTables.Count; i++) {
1098 XsdKeyTable keyTable = this.keyTables [i] as XsdKeyTable;
1099 if (keyTable.StartDepth == reader.Depth) {
1100 EndIdentityValidation (keyTable);
1102 for (int k = 0; k < keyTable.Entries.Count; k++) {
1103 XsdKeyEntry entry = keyTable.Entries [k] as XsdKeyEntry;
1104 // Remove finished (maybe key not found) entries.
1105 if (entry.StartDepth == reader.Depth) {
1107 keyTable.FinishedEntries.Add (entry);
1108 else if (entry.KeySequence.SourceSchemaIdentity is XmlSchemaKey)
1109 HandleError ("Key sequence is missing.");
1110 keyTable.Entries.RemoveAt (k);
1113 // Pop validated key depth to find two or more fields.
1115 foreach (XsdKeyEntryField kf in entry.KeyFields) {
1116 if (!kf.FieldFound && kf.FieldFoundDepth == reader.Depth) {
1117 kf.FieldFoundDepth = 0;
1118 kf.FieldFoundPath = null;
1125 for (int i = 0; i < keyTables.Count; i++) {
1126 XsdKeyTable keyseq = this.keyTables [i] as XsdKeyTable;
1127 if (keyseq.StartDepth == reader.Depth) {
1128 //Console.WriteLine ("Finishing table.");
1129 keyTables.RemoveAt (i);
1134 // Reset xsi:nil, if required.
1135 if (xsiNilDepth == reader.Depth)
1139 // 3.11.4 Identity Constraint Satisfied
1141 private void AssessStartIdentityConstraints ()
1143 tmpKeyrefPool.Clear ();
1144 if (context.Element != null && context.Element.Constraints.Count > 0) {
1145 // (a) Create new key sequences, if required.
1146 foreach (XmlSchemaIdentityConstraint ident in context.Element.Constraints) {
1147 XsdKeyTable seq = CreateNewKeyTable (ident);
1148 if (ident is XmlSchemaKeyref)
1149 tmpKeyrefPool.Add (seq);
1153 // (b) Evaluate current key sequences.
1154 foreach (XsdKeyTable seq in this.keyTables) {
1155 if (seq.SelectorMatches (this.elementQNameStack, reader) != null) {
1156 // creates and registers new entry.
1157 XsdKeyEntry entry = new XsdKeyEntry (seq, reader);
1158 seq.Entries.Add (entry);
1162 // (c) Evaluate field paths.
1163 foreach (XsdKeyTable seq in this.keyTables) {
1164 // If possible, create new field entry candidates.
1165 for (int i = 0; i < seq.Entries.Count; i++) {
1166 XsdKeyEntry entry = seq.Entries [i] as XsdKeyEntry;
1167 // if (entry.KeyFound)
1168 // FIXME: it should not be skipped for multiple key check!!
1171 entry.FieldMatches (this.elementQNameStack, this);
1172 } catch (Exception ex) { // FIXME: (wishlist) It is bad manner ;-(
1173 HandleError ("Identity field value is invalid against its data type.", ex);
1179 private XsdKeyTable CreateNewKeyTable (XmlSchemaIdentityConstraint ident)
1181 XsdKeyTable seq = new XsdKeyTable (ident, this);
1182 seq.StartDepth = reader.Depth;
1183 XmlSchemaKeyref keyref = ident as XmlSchemaKeyref;
1184 this.keyTables.Add (seq);
1188 private void EndIdentityValidation (XsdKeyTable seq)
1190 ArrayList errors = new ArrayList ();
1191 foreach (XsdKeyEntry entry in seq./*NotFound*/Entries) {
1194 if (seq.SourceSchemaIdentity is XmlSchemaKey)
1195 errors.Add ("line " + entry.SelectorLineNumber + "position " + entry.SelectorLinePosition);
1197 if (errors.Count > 0)
1198 HandleError ("Invalid identity constraints were found. Key was not found. "
1199 + String.Join (", ", errors.ToArray (typeof (string)) as string []));
1202 // Find reference target
1203 XmlSchemaKeyref xsdKeyref = seq.SourceSchemaIdentity as XmlSchemaKeyref;
1204 if (xsdKeyref != null) {
1205 for (int i = this.keyTables.Count - 1; i >= 0; i--) {
1206 XsdKeyTable target = this.keyTables [i] as XsdKeyTable;
1207 if (target.SourceSchemaIdentity == xsdKeyref.Target) {
1208 seq.ReferencedKey = target;
1209 foreach (XsdKeyEntry entry in seq.FinishedEntries) {
1210 foreach (XsdKeyEntry targetEntry in target.FinishedEntries) {
1211 if (entry.CompareIdentity (targetEntry)) {
1212 entry.KeyRefFound = true;
1219 if (seq.ReferencedKey == null)
1220 HandleError ("Target key was not found.");
1221 foreach (XsdKeyEntry entry in seq.FinishedEntries) {
1222 if (!entry.KeyRefFound)
1223 errors.Add (" line " + entry.SelectorLineNumber + ", position " + entry.SelectorLinePosition);
1225 if (errors.Count > 0)
1226 HandleError ("Invalid identity constraints were found. Referenced key was not found: "
1227 + String.Join (" / ", errors.ToArray (typeof (string)) as string []));
1231 // Overrided Methods
1233 public override void Close ()
1238 public override string GetAttribute (int i)
1240 switch (reader.NodeType) {
1241 case XmlNodeType.XmlDeclaration:
1242 case XmlNodeType.DocumentType:
1243 return reader.GetAttribute (i);
1246 if (reader.AttributeCount > i)
1247 reader.GetAttribute (i);
1248 int defIdx = i - nonDefaultAttributeCount;
1249 if (i < AttributeCount)
1250 return defaultAttributes [defIdx].DefaultValue;
1252 throw new ArgumentOutOfRangeException ("i", i, "Specified attribute index is out of range.");
1255 public override string GetAttribute (string name)
1257 switch (reader.NodeType) {
1258 case XmlNodeType.XmlDeclaration:
1259 case XmlNodeType.DocumentType:
1260 return reader.GetAttribute (name);
1263 string value = reader.GetAttribute (name);
1267 XmlQualifiedName qname = SplitQName (name);
1268 return GetDefaultAttribute (qname.Name, qname.Namespace);
1271 private XmlQualifiedName SplitQName (string name)
1273 if (!XmlChar.IsName (name))
1274 throw new ArgumentException ("Invalid name was specified.", "name");
1276 Exception ex = null;
1277 XmlQualifiedName qname = XmlSchemaUtil.ToQName (reader, name, out ex);
1279 return XmlQualifiedName.Empty;
1284 public override string GetAttribute (string localName, string ns)
1286 switch (reader.NodeType) {
1287 case XmlNodeType.XmlDeclaration:
1288 case XmlNodeType.DocumentType:
1289 return reader.GetAttribute (localName, ns);
1292 string value = reader.GetAttribute (localName, ns);
1296 return GetDefaultAttribute (localName, ns);
1299 private string GetDefaultAttribute (string localName, string ns)
1301 int idx = this.FindDefaultAttribute (localName, ns);
1303 return defaultAttributes [idx].ValidatedDefaultValue;
1308 private int FindDefaultAttribute (string localName, string ns)
1310 for (int i = 0; i < this.defaultAttributes.Length; i++) {
1311 XmlSchemaAttribute attr = defaultAttributes [i];
1312 if (attr.QualifiedName.Name == localName &&
1313 attr.QualifiedName.Namespace == ns)
1319 bool IXmlLineInfo.HasLineInfo ()
1321 return readerLineInfo != null && readerLineInfo.HasLineInfo ();
1324 public override string LookupNamespace (string prefix)
1326 return reader.LookupNamespace (prefix);
1329 public override void MoveToAttribute (int i)
1331 switch (reader.NodeType) {
1332 case XmlNodeType.XmlDeclaration:
1333 case XmlNodeType.DocumentType:
1334 reader.MoveToAttribute (i);
1338 currentQName = null;
1339 if (i < this.nonDefaultAttributeCount) {
1340 reader.MoveToAttribute (i);
1341 this.currentDefaultAttribute = -1;
1342 this.defaultAttributeConsumed = false;
1345 if (i < AttributeCount) {
1346 this.currentDefaultAttribute = i - nonDefaultAttributeCount;
1347 this.defaultAttributeConsumed = false;
1350 throw new ArgumentOutOfRangeException ("i", i, "Attribute index is out of range.");
1353 public override bool MoveToAttribute (string name)
1355 switch (reader.NodeType) {
1356 case XmlNodeType.XmlDeclaration:
1357 case XmlNodeType.DocumentType:
1358 return reader.MoveToAttribute (name);
1361 currentQName = null;
1362 bool b = reader.MoveToAttribute (name);
1364 this.currentDefaultAttribute = -1;
1365 this.defaultAttributeConsumed = false;
1369 XmlQualifiedName qname = SplitQName (name);
1370 return MoveToDefaultAttribute (qname.Name, qname.Namespace);
1373 public override bool MoveToAttribute (string localName, string ns)
1375 switch (reader.NodeType) {
1376 case XmlNodeType.XmlDeclaration:
1377 case XmlNodeType.DocumentType:
1378 return reader.MoveToAttribute (localName, ns);
1381 currentQName = null;
1382 bool b = reader.MoveToAttribute (localName, ns);
1384 this.currentDefaultAttribute = -1;
1385 this.defaultAttributeConsumed = false;
1389 return MoveToDefaultAttribute (localName, ns);
1392 private bool MoveToDefaultAttribute (string localName, string ns)
1394 int idx = this.FindDefaultAttribute (localName, ns);
1397 currentDefaultAttribute = idx;
1398 defaultAttributeConsumed = false;
1402 public override bool MoveToElement ()
1404 currentDefaultAttribute = -1;
1405 defaultAttributeConsumed = false;
1406 currentQName = null;
1407 return reader.MoveToElement ();
1410 public override bool MoveToFirstAttribute ()
1412 switch (reader.NodeType) {
1413 case XmlNodeType.XmlDeclaration:
1414 case XmlNodeType.DocumentType:
1415 return reader.MoveToFirstAttribute ();
1418 currentQName = null;
1419 if (this.nonDefaultAttributeCount > 0) {
1420 bool b = reader.MoveToFirstAttribute ();
1422 currentDefaultAttribute = -1;
1423 defaultAttributeConsumed = false;
1428 if (this.defaultAttributes.Length > 0) {
1429 currentDefaultAttribute = 0;
1430 defaultAttributeConsumed = false;
1437 public override bool MoveToNextAttribute ()
1439 switch (reader.NodeType) {
1440 case XmlNodeType.XmlDeclaration:
1441 case XmlNodeType.DocumentType:
1442 return reader.MoveToNextAttribute ();
1445 currentQName = null;
1446 if (currentDefaultAttribute >= 0) {
1447 if (defaultAttributes.Length == currentDefaultAttribute + 1)
1449 currentDefaultAttribute++;
1450 defaultAttributeConsumed = false;
1454 bool b = reader.MoveToNextAttribute ();
1456 currentDefaultAttribute = -1;
1457 defaultAttributeConsumed = false;
1461 if (defaultAttributes.Length > 0) {
1462 currentDefaultAttribute = 0;
1463 defaultAttributeConsumed = false;
1470 private void ExamineAdditionalSchema ()
1472 XmlSchema schema = null;
1473 string schemaLocation = reader.GetAttribute ("schemaLocation", XmlSchema.InstanceNamespace);
1474 if (schemaLocation != null) {
1475 string [] tmp = XmlSchemaDatatype.FromName ("NMTOKENS").ParseValue (schemaLocation, NameTable, null) as string [];
1476 if (tmp.Length % 2 != 0)
1477 HandleError ("Invalid schemaLocation attribute format.");
1478 for (int i = 0; i < tmp.Length; i += 2) {
1480 Uri absUri = new Uri ((this.BaseURI != "" ? new Uri (BaseURI) : null), tmp [i + 1]);
1481 XmlTextReader xtr = new XmlTextReader (absUri.ToString ());
1482 schema = XmlSchema.Read (xtr, null);
1483 } catch (Exception) { // FIXME: (wishlist) It is bad manner ;-(
1486 if (schema.TargetNamespace == null)
1487 schema.TargetNamespace = tmp [i];
1488 else if (schema.TargetNamespace != tmp [i])
1489 HandleError ("Specified schema has different target namespace.");
1492 if (schema != null) {
1494 schemas.Add (schema);
1495 } catch (XmlSchemaException ex) {
1500 string noNsSchemaLocation = reader.GetAttribute ("noNamespaceSchemaLocation", XmlSchema.InstanceNamespace);
1501 if (noNsSchemaLocation != null) {
1503 Uri absUri = new Uri ((this.BaseURI != "" ? new Uri (BaseURI) : null), noNsSchemaLocation);
1504 XmlTextReader xtr = new XmlTextReader (absUri.ToString ());
1505 schema = XmlSchema.Read (xtr, null);
1506 } catch (Exception) { // FIXME: (wishlist) It is bad manner ;-(
1508 if (schema != null && schema.TargetNamespace != null)
1509 HandleError ("Specified schema has different target namespace.");
1511 if (schema != null) {
1513 schemas.Add (schema);
1514 } catch (XmlSchemaException ex) {
1520 public override bool Read ()
1522 nonDefaultAttributeCount = 0;
1523 currentDefaultAttribute = -1;
1524 defaultAttributeConsumed = false;
1525 currentQName = null;
1526 thisElementId = null;
1527 defaultAttributes = new XmlSchemaAttribute [0];
1529 elementQNameStack.RemoveAt (elementQNameStack.Count - 1);
1533 bool result = reader.Read ();
1534 // 3.3.4 ElementLocallyValidElement 7 = Root Valid.
1535 if (!result && missingIDReferences.Count > 0)
1536 HandleError ("There are missing ID references: " +
1538 this.missingIDReferences.ToArray (typeof (string)) as string []));
1540 switch (reader.NodeType) {
1541 case XmlNodeType.Element:
1542 nonDefaultAttributeCount = reader.AttributeCount;
1544 if (reader.Depth == 0)
1545 ExamineAdditionalSchema ();
1547 this.elementQNameStack.Add (new XmlQualifiedName (reader.LocalName, reader.NamespaceURI));
1549 // If there is no schema information, then no validation is performed.
1550 if (schemas.Count == 0)
1553 // context.Load (reader.Depth);
1554 if (skipValidationDepth < 0 || reader.Depth <= skipValidationDepth) {
1555 if (shouldValidateCharacters) {
1556 ValidateEndCharacters ();
1557 shouldValidateCharacters = false;
1559 AssessStartElementSchemaValidity ();
1560 storedCharacters.Length = 0;
1565 if (reader.IsEmptyElement)
1566 goto case XmlNodeType.EndElement;
1568 shouldValidateCharacters = true;
1570 case XmlNodeType.EndElement:
1571 if (reader.Depth == skipValidationDepth) {
1572 skipValidationDepth = -1;
1575 // context.Load (reader.Depth);
1576 if (shouldValidateCharacters) {
1577 ValidateEndCharacters ();
1578 shouldValidateCharacters = false;
1580 AssessEndElementSchemaValidity ();
1582 storedCharacters.Length = 0;
1583 childParticleState = null;
1587 case XmlNodeType.CDATA:
1588 case XmlNodeType.SignificantWhitespace:
1589 case XmlNodeType.Text:
1590 XmlSchemaComplexType ct = context.ActualType as XmlSchemaComplexType;
1591 if (ct != null && storedCharacters.Length > 0) {
1592 switch (ct.ContentType) {
1593 case XmlSchemaContentType.ElementOnly:
1594 case XmlSchemaContentType.Empty:
1595 HandleError ("Not allowed character content was found.");
1600 ValidateCharacters ();
1607 public override bool ReadAttributeValue ()
1609 if (currentDefaultAttribute < 0)
1610 return reader.ReadAttributeValue ();
1612 if (this.defaultAttributeConsumed)
1615 defaultAttributeConsumed = true;
1620 public override string ReadInnerXml ()
1622 // MS.NET 1.0 has a serious bug here. It skips validation.
1623 return reader.ReadInnerXml ();
1626 public override string ReadOuterXml ()
1628 // MS.NET 1.0 has a serious bug here. It skips validation.
1629 return reader.ReadOuterXml ();
1633 // XmlReader.ReadString() should call derived this.Read().
1634 public override string ReadString ()
1637 return reader.ReadString ();
1639 return base.ReadString ();
1643 // This class itself does not have this feature.
1644 public override void ResolveEntity ()
1646 reader.ResolveEntity ();
1649 internal class XsdValidationContext
1651 Hashtable contextStack;
1653 public XsdValidationContext ()
1655 contextStack = new Hashtable ();
1658 // Some of them might be missing (See the spec section 5.3, and also 3.3.4).
1659 public XmlSchemaElement Element;
1660 public XsdValidationState ParticleState;
1661 public XmlSchemaAttribute [] DefaultAttributes;
1663 // Some of them might be missing (See the spec section 5.3).
1664 public object SchemaType;
1666 public object LocalTypeDefinition;
1668 public object ActualType {
1670 if (LocalTypeDefinition != null)
1671 return LocalTypeDefinition;
1677 public void Clear ()
1681 ParticleState = null;
1682 LocalTypeDefinition = null;
1685 public void PushScope (int depth)
1687 contextStack [depth] = this.MemberwiseClone ();
1690 public void PopScope (int depth)
1693 contextStack.Remove (depth + 1);
1696 public void Load (int depth)
1699 XsdValidationContext restored = (XsdValidationContext) contextStack [depth];
1700 if (restored != null) {
1701 this.Element = restored.Element;
1702 this.ParticleState = restored.ParticleState;
1703 this.SchemaType = restored.SchemaType;
1704 this.LocalTypeDefinition = restored.LocalTypeDefinition;
1710 internal class XsdValidityState
1712 ArrayList currentParticles = new ArrayList ();
1713 ArrayList occured = new ArrayList ();
1714 Hashtable xsAllConsumed = new Hashtable ();
1715 XmlSchemaParticle parciele;
1718 public XsdValidityState (XmlSchemaParticle particle)
1720 this.parciele = particle;
1721 currentParticles.Add (particle);