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 XmlSchemaComplexType ct = context.ActualType as XmlSchemaComplexType;
131 XmlSchemaAttribute attdef = ct.AttributeUses [CurrentQName] as XmlSchemaAttribute;
133 return attdef.AttributeType;
135 return SourceReaderSchemaType;
137 return SourceReaderSchemaType;
142 private object SourceReaderSchemaType {
143 get { return this.sourceReaderSchemaInfo != null ? sourceReaderSchemaInfo.SchemaType : null; }
146 // This property is never used in Mono.
147 public ValidationType ValidationType {
149 if (reportNoValidationError)
150 return ValidationType.None;
152 return ValidationType.Schema;
156 // It is used only for independent XmlReader use, not for XmlValidatingReader.
157 public object ReadTypedValue ()
159 XmlSchemaDatatype dt = SchemaType as XmlSchemaDatatype;
160 XmlSchemaSimpleType st = SchemaType as XmlSchemaSimpleType;
167 case XmlNodeType.Element:
171 storedCharacters.Length = 0;
176 case XmlNodeType.SignificantWhitespace:
177 case XmlNodeType.Text:
178 case XmlNodeType.CDATA:
179 storedCharacters.Append (Value);
181 case XmlNodeType.Comment:
187 } while (loop && !EOF);
188 return dt.ParseValue (storedCharacters.ToString (), NameTable, ParserContext.NamespaceManager);
189 case XmlNodeType.Attribute:
190 return dt.ParseValue (Value, NameTable, ParserContext.NamespaceManager);
195 public ValidationEventHandler ValidationEventHandler;
197 // Public Overrided Properties
199 public override int AttributeCount {
202 if (NodeType == XmlNodeType.Element)
203 return attributeCount;
207 return reader.AttributeCount;
209 return nonDefaultAttributeCount + defaultAttributes.Length;
213 public override string BaseURI {
214 get { return reader.BaseURI; }
217 // If this class is used to implement XmlValidatingReader,
218 // it should be left to DTDValidatingReader. In other cases,
219 // it depends on the reader's ability.
220 public override bool CanResolveEntity {
221 get { return reader.CanResolveEntity; }
224 public override int Depth {
226 if (currentDefaultAttribute < 0)
228 if (this.defaultAttributeConsumed)
229 return reader.Depth + 2;
230 return reader.Depth + 1;
234 public override bool EOF {
235 get { return reader.EOF; }
238 public override bool HasValue {
240 if (currentDefaultAttribute < 0)
241 return reader.HasValue;
246 public override bool IsDefault {
248 if (currentDefaultAttribute < 0)
249 return reader.IsDefault;
254 public override bool IsEmptyElement {
256 if (currentDefaultAttribute < 0)
257 return reader.IsEmptyElement;
262 public override string this [int i] {
263 get { return GetAttribute (i); }
266 public override string this [string name] {
267 get { return GetAttribute (name); }
270 public override string this [string localName, string ns] {
271 get { return GetAttribute (localName, ns); }
274 int IXmlLineInfo.LineNumber {
275 get { return readerLineInfo != null ? readerLineInfo.LineNumber : 0; }
278 int IXmlLineInfo.LinePosition {
279 get { return readerLineInfo != null ? readerLineInfo.LinePosition : 0; }
282 public override string LocalName {
284 if (currentDefaultAttribute < 0)
285 return reader.LocalName;
286 if (defaultAttributeConsumed)
288 return defaultAttributes [currentDefaultAttribute].QualifiedName.Name;
292 public override string Name {
294 if (currentDefaultAttribute < 0)
296 if (defaultAttributeConsumed)
299 XmlQualifiedName qname = defaultAttributes [currentDefaultAttribute].QualifiedName;
300 string prefix = Prefix;
301 if (prefix == String.Empty)
304 return String.Concat (prefix, ":", qname.Name);
308 public override string NamespaceURI {
310 if (currentDefaultAttribute < 0)
311 return reader.NamespaceURI;
312 if (defaultAttributeConsumed)
314 return defaultAttributes [currentDefaultAttribute].QualifiedName.Namespace;
318 public override XmlNameTable NameTable {
319 get { return reader.NameTable; }
322 public override XmlNodeType NodeType {
324 if (currentDefaultAttribute < 0)
325 return reader.NodeType;
326 if (defaultAttributeConsumed)
327 return XmlNodeType.Text;
328 return XmlNodeType.Attribute;
332 public XmlParserContext ParserContext {
333 get { return XmlSchemaUtil.GetParserContext (reader); }
336 public override string Prefix {
338 if (currentDefaultAttribute < 0)
339 return reader.Prefix;
340 if (defaultAttributeConsumed)
342 XmlQualifiedName qname = defaultAttributes [currentDefaultAttribute].QualifiedName;
343 string prefix = this.ParserContext.NamespaceManager.LookupPrefix (qname.Namespace);
351 public override char QuoteChar {
352 get { return reader.QuoteChar; }
355 public override ReadState ReadState {
356 get { return reader.ReadState; }
359 public override string Value {
361 if (currentDefaultAttribute < 0)
363 return defaultAttributes [currentDefaultAttribute].ValidatedDefaultValue;
367 XmlQualifiedName qnameXmlLang = new XmlQualifiedName ("lang", XmlNamespaceManager.XmlnsXml);
369 public override string XmlLang {
371 string xmlLang = reader.XmlLang;
374 int idx = this.FindDefaultAttribute ("lang", XmlNamespaceManager.XmlnsXml);
377 return defaultAttributes [idx].ValidatedDefaultValue;
381 public override XmlSpace XmlSpace {
383 XmlSpace space = reader.XmlSpace;
384 if (space != XmlSpace.None)
386 int idx = this.FindDefaultAttribute ("space", XmlNamespaceManager.XmlnsXml);
388 return XmlSpace.None;
389 return (XmlSpace) Enum.Parse (typeof (XmlSpace), defaultAttributes [idx].ValidatedDefaultValue, false);
395 private XmlQualifiedName QualifyName (string name)
397 int colonAt = name.IndexOf (':');
399 return new XmlQualifiedName (name, null);
401 return new XmlQualifiedName (name.Substring (colonAt + 1),
402 LookupNamespace (name.Substring (0, colonAt)));
405 private void HandleError (string error)
407 HandleError (error, null);
410 private void HandleError (string error, Exception innerException)
412 if (reportNoValidationError) // extra quick check
415 XmlSchemaException schemaException = new XmlSchemaException (error,
416 this, this.BaseURI, null, innerException);
417 HandleError (schemaException);
420 private void HandleError (XmlSchemaException schemaException)
422 if (reportNoValidationError)
425 ValidationEventArgs e = new ValidationEventArgs (schemaException,
426 schemaException.Message, XmlSeverityType.Error);
428 if (this.ValidationEventHandler != null)
429 this.ValidationEventHandler (this, e);
430 else if (xvReader != null)
431 xvReader.OnValidationEvent (this, e);
432 else if (e.Severity == XmlSeverityType.Error)
434 this.xvReader.OnValidationEvent (this, e);
440 private XmlSchemaElement FindElement (string name, string ns)
442 foreach (XmlSchema target in schemas) {
443 XmlSchema matches = target.Schemas [ns];
444 if (matches != null) {
445 XmlSchemaElement result = target.Elements [new XmlQualifiedName (name, ns)] as XmlSchemaElement;
453 private XmlSchemaType FindType (XmlQualifiedName qname)
455 foreach (XmlSchema target in schemas) {
456 XmlSchemaType type = target.SchemaTypes [qname] as XmlSchemaType;
463 private void ValidateStartElementParticle ()
465 stateManager.CurrentElement = null;
466 context.ParticleState = context.ParticleState.EvaluateStartElement (reader.LocalName, reader.NamespaceURI);
467 if (context.ParticleState == XsdValidationState.Invalid)
468 HandleError ("Invalid start element: " + reader.NamespaceURI + ":" + reader.LocalName);
470 context.Element = stateManager.CurrentElement;
471 if (context.Element != null)
472 context.SchemaType = context.Element.ElementType;
475 private void ValidateEndElementParticle ()
477 if (childParticleState != null) {
478 if (!childParticleState.EvaluateEndElement ()) {
479 HandleError ("Invalid end element: " + reader.Name);
482 context.PopScope (reader.Depth);
485 // Utility for missing validation completion related to child items.
486 private void ValidateCharacters ()
488 // TODO: value context validation here.
489 if (xsiNilDepth >= 0 && xsiNilDepth < reader.Depth)
490 HandleError ("Element item appeared, while current element context is nil.");
492 storedCharacters.Append (reader.Value);
495 // Utility for missing validation completion related to child items.
496 private void ValidateEndCharacters ()
498 if (context.ActualType == null)
501 string value = storedCharacters.ToString ();
503 if (storedCharacters.Length == 0) {
504 // 3.3.4 Element Locally Valid (Element) 5.1.2
505 // TODO: check entire DefaultValid (3.3.6)
506 if (context.Element != null && context.Element.ValidatedDefaultValue != null)
507 value = context.Element.ValidatedDefaultValue;
510 XmlSchemaDatatype dt = context.ActualType as XmlSchemaDatatype;
511 XmlSchemaSimpleType st = context.ActualType as XmlSchemaSimpleType;
514 // if (st.Variety == XmlSchemaDerivationMethod.Restriction)
517 XmlSchemaComplexType ct = context.ActualType as XmlSchemaComplexType;
519 switch (ct.ContentType) {
520 case XmlSchemaContentType.ElementOnly:
521 case XmlSchemaContentType.Empty:
522 if (storedCharacters.Length > 0)
523 HandleError ("Character content not allowed.");
529 // 3.3.4 Element Locally Valid (Element) :: 5.2.2.2. Fixed value constraints
530 if (context.Element != null && context.Element.ValidatedFixedValue != null)
531 if (value != context.Element.ValidatedFixedValue)
532 HandleError ("Fixed value constraint was not satisfied.");
533 AssessStringValid (st, dt, value);
536 // Identity field value
537 while (this.currentKeyFieldConsumers.Count > 0) {
538 XsdKeyEntryField field = this.currentKeyFieldConsumers [0] as XsdKeyEntryField;
539 if (field.Identity != null)
540 HandleError ("Two or more identical field was found. Former value is '" + field.Identity + "' .");
541 object identity = null;
544 identity = dt.ParseValue (value, NameTable, ParserContext.NamespaceManager);
545 } catch (Exception ex) { // FIXME: (wishlist) This is bad manner ;-(
546 HandleError ("Identity value is invalid against its data type " + dt.TokenizedType, ex);
549 if (identity == null)
552 if (!field.SetIdentityField (identity, dt as XsdAnySimpleType, this))
553 HandleError ("Two or more identical key value was found: '" + value + "' .");
554 this.currentKeyFieldConsumers.RemoveAt (0);
557 shouldValidateCharacters = false;
560 // 3.14.4 String Valid
561 private void AssessStringValid (XmlSchemaSimpleType st,
562 XmlSchemaDatatype dt, string value)
564 XmlSchemaDatatype validatedDatatype = dt;
566 string normalized = validatedDatatype.Normalize (value);
568 XmlSchemaDatatype itemDatatype;
569 XmlSchemaSimpleType itemSimpleType;
570 switch (st.DerivedBy) {
571 case XmlSchemaDerivationMethod.List:
572 XmlSchemaSimpleTypeList listContent = st.Content as XmlSchemaSimpleTypeList;
573 values = normalized.Split (wsChars);
574 itemDatatype = listContent.ValidatedListItemType as XmlSchemaDatatype;
575 itemSimpleType = listContent.ValidatedListItemType as XmlSchemaSimpleType;
576 foreach (string each in values) {
577 if (each == String.Empty)
579 // validate against ValidatedItemType
580 if (itemDatatype != null) {
582 itemDatatype.ParseValue (each, NameTable, ParserContext.NamespaceManager);
583 } catch (Exception ex) { // FIXME: (wishlist) better exception handling ;-(
584 HandleError ("List type value contains one or more invalid values.", ex);
589 AssessStringValid (itemSimpleType, itemSimpleType.Datatype, each);
592 case XmlSchemaDerivationMethod.Union:
593 XmlSchemaSimpleTypeUnion union = st.Content as XmlSchemaSimpleTypeUnion;
595 string each = normalized;
596 // validate against ValidatedItemType
598 foreach (object eachType in union.ValidatedTypes) {
599 itemDatatype = eachType as XmlSchemaDatatype;
600 itemSimpleType = eachType as XmlSchemaSimpleType;
601 if (itemDatatype != null) {
603 itemDatatype.ParseValue (each, NameTable, ParserContext.NamespaceManager);
604 } catch (Exception) { // FIXME: (wishlist) better exception handling ;-(
610 AssessStringValid (itemSimpleType, itemSimpleType.Datatype, each);
611 } catch (XmlSchemaException) {
619 HandleError ("Union type value contains one or more invalid values.");
624 case XmlSchemaDerivationMethod.Restriction:
625 XmlSchemaSimpleTypeRestriction str = st.Content as XmlSchemaSimpleTypeRestriction;
628 /* Don't forget to validate against inherited type's facets
629 * Could we simplify this by assuming that the basetype will also
632 // mmm, will check later.
633 XmlSchemaSimpleType baseType = str.ActualBaseSchemaType as XmlSchemaSimpleType;
634 if (baseType != null) {
635 AssessStringValid(baseType, dt, normalized);
637 if (!str.ValidateValueWithFacets (normalized, NameTable)) {
638 HandleError ("Specified value was invalid against the facets.");
642 validatedDatatype = st.Datatype;
646 if (validatedDatatype != null) {
648 validatedDatatype.ParseValue (value, NameTable, ParserContext.NamespaceManager);
649 } catch (Exception ex) { // FIXME: (wishlist) It is bad manner ;-(
650 HandleError ("Invalidly typed data was specified.", ex);
655 private object GetLocalTypeDefinition (string name)
657 object xsiType = null;
658 XmlQualifiedName typeQName = QualifyName (name);
659 if (typeQName.Namespace == XmlSchema.Namespace) {
660 if (typeQName.Name == "anyType")
661 xsiType = XmlSchemaComplexType.AnyType;
663 xsiType = XmlSchemaDatatype.FromName (typeQName);
666 xsiType = FindType (typeQName);
670 // It is common to ElementLocallyValid::4 and SchemaValidityAssessment::1.2.1.2.4
671 private void AssessLocalTypeDerivationOK (object xsiType, object baseType, XmlSchemaDerivationMethod flag)
673 XmlSchemaType xsiSchemaType = xsiType as XmlSchemaType;
674 XmlSchemaComplexType baseComplexType = baseType as XmlSchemaComplexType;
675 XmlSchemaComplexType xsiComplexType = xsiSchemaType as XmlSchemaComplexType;
676 if (xsiType != baseType) {
677 // Extracted (not extraneous) check for 3.4.6 TypeDerivationOK.
678 if (baseComplexType != null)
679 flag |= baseComplexType.BlockResolved;
680 if (flag == XmlSchemaDerivationMethod.All) {
681 HandleError ("Prohibited element type substitution.");
683 } else if (xsiSchemaType != null && (flag & xsiSchemaType.DerivedBy) != 0) {
684 HandleError ("Prohibited element type substitution.");
689 if (xsiComplexType != null)
691 xsiComplexType.ValidateTypeDerivationOK (baseType, null, null);
692 } catch (XmlSchemaException ex) {
693 // HandleError ("Locally specified schema complex type derivation failed. " + ex.Message, ex);
697 XmlSchemaSimpleType xsiSimpleType = xsiType as XmlSchemaSimpleType;
698 if (xsiSimpleType != null) {
700 xsiSimpleType.ValidateTypeDerivationOK (baseType, null, null, true);
701 } catch (XmlSchemaException ex) {
702 // HandleError ("Locally specified schema simple type derivation failed. " + ex.Message, ex);
706 else if (xsiType is XmlSchemaDatatype) {
710 HandleError ("Primitive data type cannot be derived type using xsi:type specification.");
714 // Section 3.3.4 of the spec.
715 private void AssessStartElementSchemaValidity ()
717 // If the reader is inside xsi:nil (and failed on validation),
718 // then simply skip its content.
719 if (xsiNilDepth >= 0 && xsiNilDepth < reader.Depth)
720 HandleError ("Element item appeared, while current element context is nil.");
722 context.Load (reader.Depth);
723 if (childParticleState != null) {
724 context.ParticleState = childParticleState;
725 childParticleState = null;
728 // If validation state exists, then first assess particle validity.
729 if (context.ParticleState != null) {
730 ValidateStartElementParticle ();
733 string xsiNilValue = GetAttribute ("nil", XmlSchema.InstanceNamespace);
734 if (xsiNilValue != null)
735 xsiNilValue = xsiNilValue.Trim (XmlChar.WhitespaceChars);
736 bool isXsiNil = xsiNilValue == "true";
737 if (isXsiNil && this.xsiNilDepth < 0)
738 xsiNilDepth = reader.Depth;
740 // [Schema Validity Assessment (Element) 1.2]
741 // Evaluate "local type definition" from xsi:type.
742 // (See spec 3.3.4 Schema Validity Assessment (Element) 1.2.1.2.3.
743 // Note that Schema Validity Assessment(Element) 1.2 takes
744 // precedence than 1.1 of that.
746 string xsiTypeName = reader.GetAttribute ("type", XmlSchema.InstanceNamespace);
747 if (xsiTypeName != null) {
748 xsiTypeName = xsiTypeName.Trim (XmlChar.WhitespaceChars);
749 object xsiType = GetLocalTypeDefinition (xsiTypeName);
751 HandleError ("The instance type was not found: " + xsiTypeName + " .");
753 XmlSchemaType xsiSchemaType = xsiType as XmlSchemaType;
754 if (xsiSchemaType != null && this.context.Element != null) {
755 XmlSchemaType elemBaseType = context.Element.ElementType as XmlSchemaType;
756 if (elemBaseType != null && (xsiSchemaType.DerivedBy & elemBaseType.FinalResolved) != 0)
757 HandleError ("The instance type is prohibited by the type of the context element.");
758 if (elemBaseType != xsiType && (xsiSchemaType.DerivedBy & this.context.Element.BlockResolved) != 0)
759 HandleError ("The instance type is prohibited by the context element.");
761 XmlSchemaComplexType xsiComplexType = xsiType as XmlSchemaComplexType;
762 if (xsiComplexType != null && xsiComplexType.IsAbstract)
763 HandleError ("The instance type is abstract: " + xsiTypeName + " .");
765 // If current schema type exists, then this xsi:type must be
766 // valid extension of that type. See 1.2.1.2.4.
767 if (context.Element != null) {
768 // FIXME: supply *correct* base type
769 AssessLocalTypeDerivationOK (xsiType, context.Element.ElementType, context.Element.BlockResolved);
771 AssessStartElementLocallyValidType (xsiType); // 1.2.2:
772 context.LocalTypeDefinition = xsiType;
777 // Create Validation Root, if not exist.
778 // [Schema Validity Assessment (Element) 1.1]
779 if (context.Element == null)
780 context.Element = FindElement (reader.LocalName, reader.NamespaceURI);
781 if (context.Element != null) {
782 if (xsiTypeName == null) {
783 context.SchemaType = context.Element.ElementType;
784 AssessElementLocallyValidElement (context.Element, xsiNilValue); // 1.1.2
788 switch (stateManager.ProcessContents) {
789 case XmlSchemaContentProcessing.Skip:
791 case XmlSchemaContentProcessing.Lax:
793 schema = schemas [reader.NamespaceURI];
794 if (schema != null && !schema.missedSubComponents)
795 HandleError ("Element declaration for " + reader.LocalName + " is missing.");
799 schema = schemas [reader.NamespaceURI];
800 if (xsiTypeName == null && (schema == null || !schema.missedSubComponents))
801 HandleError ("Element declaration for " + reader.LocalName + " is missing.");
806 if (stateManager.ProcessContents == XmlSchemaContentProcessing.Skip)
807 skipValidationDepth = reader.Depth;
809 // Finally, create child particle state.
810 XmlSchemaComplexType xsComplexType = SchemaType as XmlSchemaComplexType;
811 if (xsComplexType != null)
812 childParticleState = stateManager.Create (xsComplexType.ContentTypeParticle);
813 else if (stateManager.ProcessContents == XmlSchemaContentProcessing.Lax)
814 childParticleState = stateManager.Create (XmlSchemaAny.AnyTypeContent);
816 childParticleState = stateManager.Create (XmlSchemaParticle.Empty);
818 AssessStartIdentityConstraints ();
820 context.PushScope (reader.Depth);
823 // 3.3.4 Element Locally Valid (Element)
824 private void AssessElementLocallyValidElement (XmlSchemaElement element, string xsiNilValue)
826 XmlQualifiedName qname = new XmlQualifiedName (reader.LocalName, reader.NamespaceURI);
829 HandleError ("Element declaration is required for " + qname);
831 if (element.ActualIsAbstract)
832 HandleError ("Abstract element declaration was specified for " + qname);
834 if (!element.ActualIsNillable && xsiNilValue != null)
835 HandleError ("This element declaration is not nillable: " + qname);
837 // Note that 3.2.1 xsi:nil constraints are to be validated in
838 else if (xsiNilValue == "true") {
839 // AssessElementSchemaValidity() and ValidateCharacters()
841 if (element.ValidatedFixedValue != null)
842 HandleError ("Schema instance nil was specified, where the element declaration for " + qname + "has fixed value constraints.");
845 string xsiType = reader.GetAttribute ("type", XmlSchema.InstanceNamespace);
846 if (xsiType != null) {
847 context.LocalTypeDefinition = GetLocalTypeDefinition (xsiType);
848 AssessLocalTypeDerivationOK (context.LocalTypeDefinition, element.ElementType, element.BlockResolved);
851 // 5 Not all things cannot be assessed here.
852 // It is common to 5.1 and 5.2
853 if (element.ElementType != null)
854 AssessStartElementLocallyValidType (SchemaType);
856 // 6. should be out from here.
857 // See invokation of AssessStartIdentityConstraints().
859 // 7 is going to be validated in Read() (in case of xmlreader's EOF).
862 // 3.3.4 Element Locally Valid (Type)
863 private void AssessStartElementLocallyValidType (object schemaType)
865 if (schemaType == null) { // 1.
866 HandleError ("Schema type does not exist.");
869 XmlSchemaComplexType cType = schemaType as XmlSchemaComplexType;
870 XmlSchemaSimpleType sType = schemaType as XmlSchemaSimpleType;
873 while (reader.MoveToNextAttribute ()) {
874 if (reader.NamespaceURI == XmlNamespaceManager.XmlnsXmlns)
876 if (reader.NamespaceURI != XmlSchema.InstanceNamespace)
877 HandleError ("Current simple type cannot accept attributes other than schema instance namespace.");
878 switch (reader.LocalName) {
881 case "schemaLocation":
882 case "noNamespaceSchemaLocation":
885 HandleError ("Unknown schema instance namespace attribute: " + reader.LocalName);
889 reader.MoveToElement ();
890 // 3.1.2 and 3.1.3 cannot be assessed here.
891 } else if (cType != null) {
892 if (cType.IsAbstract) { // 2.
893 HandleError ("Target complex type is abstract.");
897 AssessElementLocallyValidComplexType (cType);
901 // 3.4.4 Element Locally Valid (Complex Type)
902 // TODO ("wild IDs constraints.")
903 private void AssessElementLocallyValidComplexType (XmlSchemaComplexType cType)
906 if (cType.IsAbstract)
907 HandleError ("Target complex type is abstract.");
909 // 2 (xsi:nil and content prohibition)
910 // See AssessStartElementSchemaValidity() and ValidateCharacters()
912 string elementNs = reader.NamespaceURI;
913 // 3. attribute uses and
915 while (reader.MoveToNextAttribute ()) {
916 if (reader.NamespaceURI == "http://www.w3.org/2000/xmlns/")
918 else if (reader.NamespaceURI == XmlSchema.InstanceNamespace)
920 XmlQualifiedName qname = new XmlQualifiedName (reader.LocalName, reader.NamespaceURI);
921 object attMatch = FindAttributeDeclaration (cType, qname, elementNs);
922 if (attMatch == null)
923 HandleError ("Attribute declaration was not found for " + qname);
925 XmlSchemaAttribute attdecl = attMatch as XmlSchemaAttribute;
926 if (attdecl == null) { // i.e. anyAttribute
927 XmlSchemaAnyAttribute anyAttrMatch = attMatch as XmlSchemaAnyAttribute;
929 AssessAttributeLocallyValidUse (attdecl);
930 AssessAttributeLocallyValid (attdecl, true);
934 reader.MoveToElement ();
936 // Collect default attributes.
938 // FIXME: FixedValue check maybe extraneous.
939 foreach (DictionaryEntry entry in cType.AttributeUses) {
940 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
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 (DictionaryEntry entry in schema.Attributes) {
989 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
990 if (attr.QualifiedName == qname)
994 if (cType.AttributeWildcard.ProcessContents == XmlSchemaContentProcessing.Lax)
995 return cType.AttributeWildcard;
1000 // 3.2.4 Attribute Locally Valid and 3.4.4 - 5.wildIDs
1002 private void AssessAttributeLocallyValid (XmlSchemaAttribute attr, bool checkWildIDs)
1005 switch (reader.NamespaceURI) {
1006 case XmlNamespaceManager.XmlnsXml:
1007 case XmlNamespaceManager.XmlnsXmlns:
1008 case XmlSchema.InstanceNamespace:
1012 if (attr.AttributeType == null)
1013 HandleError ("Attribute type is missing for " + attr.QualifiedName);
1014 XmlSchemaDatatype dt = attr.AttributeType as XmlSchemaDatatype;
1016 dt = ((XmlSchemaSimpleType) attr.AttributeType).Datatype;
1017 // It is a bit heavy process, so let's omit as long as possible ;-)
1018 if (dt != XmlSchemaSimpleType.AnySimpleType || attr.ValidatedFixedValue != null) {
1019 string normalized = dt.Normalize (reader.Value);
1020 object parsedValue = null;
1022 dt.ParseValue (normalized, reader.NameTable, this.ParserContext.NamespaceManager);
1023 } catch (Exception ex) { // FIXME: (wishlist) It is bad manner ;-(
1024 HandleError ("Attribute value is invalid against its data type " + dt.TokenizedType, ex);
1026 if (attr.ValidatedFixedValue != null && attr.ValidatedFixedValue != normalized)
1027 HandleError ("The value of the attribute " + attr.QualifiedName + " does not match with its fixed value.");
1028 // FIXME: this is extraneous checks in 3.2.4 Attribute Locally Valid.
1030 AssessEachAttributeIdentityConstraint (dt, normalized, parsedValue);
1034 private void AssessEachAttributeIdentityConstraint (XmlSchemaDatatype dt,
1035 string normalized, object parsedValue)
1037 // Get normalized value and (if required) parsedValue if missing.
1038 switch (dt.TokenizedType) {
1039 case XmlTokenizedType.IDREFS:
1040 if (normalized == null)
1041 normalized = dt.Normalize (reader.Value);
1042 if (parsedValue == null)
1043 parsedValue = dt.ParseValue (normalized, reader.NameTable, ParserContext.NamespaceManager);
1045 case XmlTokenizedType.ID:
1046 case XmlTokenizedType.IDREF:
1047 if (normalized == null)
1048 normalized = dt.Normalize (reader.Value);
1052 // Validate identity constraints.
1053 switch (dt.TokenizedType) {
1054 case XmlTokenizedType.ID:
1055 if (thisElementId != null)
1056 HandleError ("ID type attribute was already assigned in the containing element.");
1057 thisElementId = normalized;
1058 idList.Add (normalized);
1060 case XmlTokenizedType.IDREF:
1061 if (missingIDReferences.Contains (normalized))
1062 missingIDReferences.Remove (normalized);
1064 missingIDReferences.Add (normalized);
1066 case XmlTokenizedType.IDREFS:
1067 foreach (string id in (string []) parsedValue) {
1068 if (missingIDReferences.Contains (id))
1069 missingIDReferences.Remove (id);
1071 missingIDReferences.Add (id);
1078 private void AssessAttributeLocallyValidUse (XmlSchemaAttribute attr)
1080 // TODO: value constraint check
1081 // This is extra check than spec 3.5.4
1082 if (attr.ValidatedUse == XmlSchemaUse.Prohibited)
1083 HandleError ("Attribute " + attr.QualifiedName + " is prohibited in this context.");
1086 private void AssessEndElementSchemaValidity ()
1088 if (childParticleState == null)
1089 childParticleState = context.ParticleState;
1090 ValidateEndElementParticle (); // validate against childrens' state.
1092 context.Load (reader.Depth);
1094 // 3.3.4 Assess ElementLocallyValidElement 5: value constraints.
1095 // 3.3.4 Assess ElementLocallyValidType 3.1.3. = StringValid(3.14.4)
1096 // => ValidateEndCharacters().
1098 // Reset Identity constraints.
1099 for (int i = 0; i < keyTables.Count; i++) {
1100 XsdKeyTable keyTable = this.keyTables [i] as XsdKeyTable;
1101 if (keyTable.StartDepth == reader.Depth) {
1102 EndIdentityValidation (keyTable);
1104 for (int k = 0; k < keyTable.Entries.Count; k++) {
1105 XsdKeyEntry entry = keyTable.Entries [k] as XsdKeyEntry;
1106 // Remove finished (maybe key not found) entries.
1107 if (entry.StartDepth == reader.Depth) {
1109 keyTable.FinishedEntries.Add (entry);
1110 else if (entry.KeySequence.SourceSchemaIdentity is XmlSchemaKey)
1111 HandleError ("Key sequence is missing.");
1112 keyTable.Entries.RemoveAt (k);
1115 // Pop validated key depth to find two or more fields.
1117 foreach (XsdKeyEntryField kf in entry.KeyFields) {
1118 if (!kf.FieldFound && kf.FieldFoundDepth == reader.Depth) {
1119 kf.FieldFoundDepth = 0;
1120 kf.FieldFoundPath = null;
1127 for (int i = 0; i < keyTables.Count; i++) {
1128 XsdKeyTable keyseq = this.keyTables [i] as XsdKeyTable;
1129 if (keyseq.StartDepth == reader.Depth) {
1130 //Console.WriteLine ("Finishing table.");
1131 keyTables.RemoveAt (i);
1136 // Reset xsi:nil, if required.
1137 if (xsiNilDepth == reader.Depth)
1141 // 3.11.4 Identity Constraint Satisfied
1143 private void AssessStartIdentityConstraints ()
1145 tmpKeyrefPool.Clear ();
1146 if (context.Element != null && context.Element.Constraints.Count > 0) {
1147 // (a) Create new key sequences, if required.
1148 foreach (XmlSchemaIdentityConstraint ident in context.Element.Constraints) {
1149 XsdKeyTable seq = CreateNewKeyTable (ident);
1150 if (ident is XmlSchemaKeyref)
1151 tmpKeyrefPool.Add (seq);
1155 // (b) Evaluate current key sequences.
1156 foreach (XsdKeyTable seq in this.keyTables) {
1157 if (seq.SelectorMatches (this.elementQNameStack, reader) != null) {
1158 // creates and registers new entry.
1159 XsdKeyEntry entry = new XsdKeyEntry (seq, reader);
1160 seq.Entries.Add (entry);
1164 // (c) Evaluate field paths.
1165 foreach (XsdKeyTable seq in this.keyTables) {
1166 // If possible, create new field entry candidates.
1167 for (int i = 0; i < seq.Entries.Count; i++) {
1168 XsdKeyEntry entry = seq.Entries [i] as XsdKeyEntry;
1169 // if (entry.KeyFound)
1170 // FIXME: it should not be skipped for multiple key check!!
1173 entry.FieldMatches (this.elementQNameStack, this);
1174 } catch (Exception ex) { // FIXME: (wishlist) It is bad manner ;-(
1175 HandleError ("Identity field value is invalid against its data type.", ex);
1181 private XsdKeyTable CreateNewKeyTable (XmlSchemaIdentityConstraint ident)
1183 XsdKeyTable seq = new XsdKeyTable (ident, this);
1184 seq.StartDepth = reader.Depth;
1185 XmlSchemaKeyref keyref = ident as XmlSchemaKeyref;
1186 this.keyTables.Add (seq);
1190 private void EndIdentityValidation (XsdKeyTable seq)
1192 ArrayList errors = new ArrayList ();
1193 foreach (XsdKeyEntry entry in seq./*NotFound*/Entries) {
1196 if (seq.SourceSchemaIdentity is XmlSchemaKey)
1197 errors.Add ("line " + entry.SelectorLineNumber + "position " + entry.SelectorLinePosition);
1199 if (errors.Count > 0)
1200 HandleError ("Invalid identity constraints were found. Key was not found. "
1201 + String.Join (", ", errors.ToArray (typeof (string)) as string []));
1204 // Find reference target
1205 XmlSchemaKeyref xsdKeyref = seq.SourceSchemaIdentity as XmlSchemaKeyref;
1206 if (xsdKeyref != null) {
1207 for (int i = this.keyTables.Count - 1; i >= 0; i--) {
1208 XsdKeyTable target = this.keyTables [i] as XsdKeyTable;
1209 if (target.SourceSchemaIdentity == xsdKeyref.Target) {
1210 seq.ReferencedKey = target;
1211 foreach (XsdKeyEntry entry in seq.FinishedEntries) {
1212 foreach (XsdKeyEntry targetEntry in target.FinishedEntries) {
1213 if (entry.CompareIdentity (targetEntry)) {
1214 entry.KeyRefFound = true;
1221 if (seq.ReferencedKey == null)
1222 HandleError ("Target key was not found.");
1223 foreach (XsdKeyEntry entry in seq.FinishedEntries) {
1224 if (!entry.KeyRefFound)
1225 errors.Add (" line " + entry.SelectorLineNumber + ", position " + entry.SelectorLinePosition);
1227 if (errors.Count > 0)
1228 HandleError ("Invalid identity constraints were found. Referenced key was not found: "
1229 + String.Join (" / ", errors.ToArray (typeof (string)) as string []));
1233 // Overrided Methods
1235 public override void Close ()
1240 public override string GetAttribute (int i)
1242 switch (reader.NodeType) {
1243 case XmlNodeType.XmlDeclaration:
1244 case XmlNodeType.DocumentType:
1245 return reader.GetAttribute (i);
1248 if (reader.AttributeCount > i)
1249 reader.GetAttribute (i);
1250 int defIdx = i - nonDefaultAttributeCount;
1251 if (i < AttributeCount)
1252 return defaultAttributes [defIdx].DefaultValue;
1254 throw new ArgumentOutOfRangeException ("i", i, "Specified attribute index is out of range.");
1257 public override string GetAttribute (string name)
1259 switch (reader.NodeType) {
1260 case XmlNodeType.XmlDeclaration:
1261 case XmlNodeType.DocumentType:
1262 return reader.GetAttribute (name);
1265 string value = reader.GetAttribute (name);
1269 XmlQualifiedName qname = SplitQName (name);
1270 return GetDefaultAttribute (qname.Name, qname.Namespace);
1273 private XmlQualifiedName SplitQName (string name)
1275 if (!XmlChar.IsName (name))
1276 throw new ArgumentException ("Invalid name was specified.", "name");
1278 Exception ex = null;
1279 XmlQualifiedName qname = XmlSchemaUtil.ToQName (reader, name, out ex);
1281 return XmlQualifiedName.Empty;
1286 public override string GetAttribute (string localName, string ns)
1288 switch (reader.NodeType) {
1289 case XmlNodeType.XmlDeclaration:
1290 case XmlNodeType.DocumentType:
1291 return reader.GetAttribute (localName, ns);
1294 string value = reader.GetAttribute (localName, ns);
1298 return GetDefaultAttribute (localName, ns);
1301 private string GetDefaultAttribute (string localName, string ns)
1303 int idx = this.FindDefaultAttribute (localName, ns);
1305 return defaultAttributes [idx].ValidatedDefaultValue;
1310 private int FindDefaultAttribute (string localName, string ns)
1312 for (int i = 0; i < this.defaultAttributes.Length; i++) {
1313 XmlSchemaAttribute attr = defaultAttributes [i];
1314 if (attr.QualifiedName.Name == localName &&
1315 (ns == null || attr.QualifiedName.Namespace == ns))
1321 bool IXmlLineInfo.HasLineInfo ()
1323 return readerLineInfo != null && readerLineInfo.HasLineInfo ();
1326 public override string LookupNamespace (string prefix)
1328 return reader.LookupNamespace (prefix);
1331 public override void MoveToAttribute (int i)
1333 switch (reader.NodeType) {
1334 case XmlNodeType.XmlDeclaration:
1335 case XmlNodeType.DocumentType:
1336 reader.MoveToAttribute (i);
1340 currentQName = null;
1341 if (i < this.nonDefaultAttributeCount) {
1342 reader.MoveToAttribute (i);
1343 this.currentDefaultAttribute = -1;
1344 this.defaultAttributeConsumed = false;
1347 if (i < AttributeCount) {
1348 this.currentDefaultAttribute = i - nonDefaultAttributeCount;
1349 this.defaultAttributeConsumed = false;
1352 throw new ArgumentOutOfRangeException ("i", i, "Attribute index is out of range.");
1355 public override bool MoveToAttribute (string name)
1357 switch (reader.NodeType) {
1358 case XmlNodeType.XmlDeclaration:
1359 case XmlNodeType.DocumentType:
1360 return reader.MoveToAttribute (name);
1363 currentQName = null;
1364 bool b = reader.MoveToAttribute (name);
1366 this.currentDefaultAttribute = -1;
1367 this.defaultAttributeConsumed = false;
1371 return MoveToDefaultAttribute (name, null);
1374 public override bool MoveToAttribute (string localName, string ns)
1376 switch (reader.NodeType) {
1377 case XmlNodeType.XmlDeclaration:
1378 case XmlNodeType.DocumentType:
1379 return reader.MoveToAttribute (localName, ns);
1382 currentQName = null;
1383 bool b = reader.MoveToAttribute (localName, ns);
1385 this.currentDefaultAttribute = -1;
1386 this.defaultAttributeConsumed = false;
1390 return MoveToDefaultAttribute (localName, ns);
1393 private bool MoveToDefaultAttribute (string localName, string ns)
1395 int idx = this.FindDefaultAttribute (localName, ns);
1398 currentDefaultAttribute = idx;
1399 defaultAttributeConsumed = false;
1403 public override bool MoveToElement ()
1405 currentDefaultAttribute = -1;
1406 defaultAttributeConsumed = false;
1407 currentQName = null;
1408 return reader.MoveToElement ();
1411 public override bool MoveToFirstAttribute ()
1413 switch (reader.NodeType) {
1414 case XmlNodeType.XmlDeclaration:
1415 case XmlNodeType.DocumentType:
1416 return reader.MoveToFirstAttribute ();
1419 currentQName = null;
1420 if (this.nonDefaultAttributeCount > 0) {
1421 bool b = reader.MoveToFirstAttribute ();
1423 currentDefaultAttribute = -1;
1424 defaultAttributeConsumed = false;
1429 if (this.defaultAttributes.Length > 0) {
1430 currentDefaultAttribute = 0;
1431 defaultAttributeConsumed = false;
1438 public override bool MoveToNextAttribute ()
1440 switch (reader.NodeType) {
1441 case XmlNodeType.XmlDeclaration:
1442 case XmlNodeType.DocumentType:
1443 return reader.MoveToNextAttribute ();
1446 currentQName = null;
1447 if (currentDefaultAttribute >= 0) {
1448 if (defaultAttributes.Length == currentDefaultAttribute + 1)
1450 currentDefaultAttribute++;
1451 defaultAttributeConsumed = false;
1455 bool b = reader.MoveToNextAttribute ();
1457 currentDefaultAttribute = -1;
1458 defaultAttributeConsumed = false;
1462 if (defaultAttributes.Length > 0) {
1463 currentDefaultAttribute = 0;
1464 defaultAttributeConsumed = false;
1471 private void ExamineAdditionalSchema ()
1473 XmlSchema schema = null;
1474 string schemaLocation = reader.GetAttribute ("schemaLocation", XmlSchema.InstanceNamespace);
1475 if (schemaLocation != null) {
1476 string [] tmp = XmlSchemaDatatype.FromName ("NMTOKENS").ParseValue (schemaLocation, NameTable, null) as string [];
1477 if (tmp.Length % 2 != 0)
1478 HandleError ("Invalid schemaLocation attribute format.");
1479 for (int i = 0; i < tmp.Length; i += 2) {
1481 Uri absUri = new Uri ((this.BaseURI != "" ? new Uri (BaseURI) : null), tmp [i + 1]);
1482 XmlTextReader xtr = new XmlTextReader (absUri.ToString ());
1483 schema = XmlSchema.Read (xtr, null);
1484 } catch (Exception) { // FIXME: (wishlist) It is bad manner ;-(
1487 if (schema.TargetNamespace == null)
1488 schema.TargetNamespace = tmp [i];
1489 else if (schema.TargetNamespace != tmp [i])
1490 HandleError ("Specified schema has different target namespace.");
1493 if (schema != null) {
1495 schemas.Add (schema);
1496 } catch (XmlSchemaException ex) {
1501 string noNsSchemaLocation = reader.GetAttribute ("noNamespaceSchemaLocation", XmlSchema.InstanceNamespace);
1502 if (noNsSchemaLocation != null) {
1504 Uri absUri = new Uri ((this.BaseURI != "" ? new Uri (BaseURI) : null), noNsSchemaLocation);
1505 XmlTextReader xtr = new XmlTextReader (absUri.ToString ());
1506 schema = XmlSchema.Read (xtr, null);
1507 } catch (Exception) { // FIXME: (wishlist) It is bad manner ;-(
1509 if (schema != null && schema.TargetNamespace != null)
1510 HandleError ("Specified schema has different target namespace.");
1512 if (schema != null) {
1514 schemas.Add (schema);
1515 } catch (XmlSchemaException ex) {
1521 public override bool Read ()
1523 nonDefaultAttributeCount = 0;
1524 currentDefaultAttribute = -1;
1525 defaultAttributeConsumed = false;
1526 currentQName = null;
1527 thisElementId = null;
1528 defaultAttributes = new XmlSchemaAttribute [0];
1530 elementQNameStack.RemoveAt (elementQNameStack.Count - 1);
1534 bool result = reader.Read ();
1535 // 3.3.4 ElementLocallyValidElement 7 = Root Valid.
1536 if (!result && missingIDReferences.Count > 0)
1537 HandleError ("There are missing ID references: " +
1539 this.missingIDReferences.ToArray (typeof (string)) as string []));
1541 switch (reader.NodeType) {
1542 case XmlNodeType.Element:
1543 nonDefaultAttributeCount = reader.AttributeCount;
1545 if (reader.Depth == 0)
1546 ExamineAdditionalSchema ();
1548 this.elementQNameStack.Add (new XmlQualifiedName (reader.LocalName, reader.NamespaceURI));
1550 // If there is no schema information, then no validation is performed.
1551 if (schemas.Count == 0)
1554 // context.Load (reader.Depth);
1555 if (skipValidationDepth < 0 || reader.Depth <= skipValidationDepth) {
1556 if (shouldValidateCharacters) {
1557 ValidateEndCharacters ();
1558 shouldValidateCharacters = false;
1560 AssessStartElementSchemaValidity ();
1561 storedCharacters.Length = 0;
1566 if (reader.IsEmptyElement)
1567 goto case XmlNodeType.EndElement;
1569 shouldValidateCharacters = true;
1571 case XmlNodeType.EndElement:
1572 if (reader.Depth == skipValidationDepth) {
1573 skipValidationDepth = -1;
1576 // context.Load (reader.Depth);
1577 if (shouldValidateCharacters) {
1578 ValidateEndCharacters ();
1579 shouldValidateCharacters = false;
1581 AssessEndElementSchemaValidity ();
1583 storedCharacters.Length = 0;
1584 childParticleState = null;
1588 case XmlNodeType.CDATA:
1589 case XmlNodeType.SignificantWhitespace:
1590 case XmlNodeType.Text:
1591 XmlSchemaComplexType ct = context.ActualType as XmlSchemaComplexType;
1592 if (ct != null && storedCharacters.Length > 0) {
1593 switch (ct.ContentType) {
1594 case XmlSchemaContentType.ElementOnly:
1595 case XmlSchemaContentType.Empty:
1596 HandleError ("Not allowed character content was found.");
1601 ValidateCharacters ();
1608 public override bool ReadAttributeValue ()
1610 if (currentDefaultAttribute < 0)
1611 return reader.ReadAttributeValue ();
1613 if (this.defaultAttributeConsumed)
1616 defaultAttributeConsumed = true;
1621 public override string ReadInnerXml ()
1623 // MS.NET 1.0 has a serious bug here. It skips validation.
1624 return reader.ReadInnerXml ();
1627 public override string ReadOuterXml ()
1629 // MS.NET 1.0 has a serious bug here. It skips validation.
1630 return reader.ReadOuterXml ();
1634 // XmlReader.ReadString() should call derived this.Read().
1635 public override string ReadString ()
1638 return reader.ReadString ();
1640 return base.ReadString ();
1644 // This class itself does not have this feature.
1645 public override void ResolveEntity ()
1647 reader.ResolveEntity ();
1650 internal class XsdValidationContext
1652 Hashtable contextStack;
1654 public XsdValidationContext ()
1656 contextStack = new Hashtable ();
1659 // Some of them might be missing (See the spec section 5.3, and also 3.3.4).
1660 public XmlSchemaElement Element;
1661 public XsdValidationState ParticleState;
1662 public XmlSchemaAttribute [] DefaultAttributes;
1664 // Some of them might be missing (See the spec section 5.3).
1665 public object SchemaType;
1667 public object LocalTypeDefinition;
1669 public object ActualType {
1671 if (LocalTypeDefinition != null)
1672 return LocalTypeDefinition;
1678 public void Clear ()
1682 ParticleState = null;
1683 LocalTypeDefinition = null;
1686 public void PushScope (int depth)
1688 contextStack [depth] = this.MemberwiseClone ();
1691 public void PopScope (int depth)
1694 contextStack.Remove (depth + 1);
1697 public void Load (int depth)
1700 XsdValidationContext restored = (XsdValidationContext) contextStack [depth];
1701 if (restored != null) {
1702 this.Element = restored.Element;
1703 this.ParticleState = restored.ParticleState;
1704 this.SchemaType = restored.SchemaType;
1705 this.LocalTypeDefinition = restored.LocalTypeDefinition;
1711 internal class XsdValidityState
1713 ArrayList currentParticles = new ArrayList ();
1714 ArrayList occured = new ArrayList ();
1715 Hashtable xsAllConsumed = new Hashtable ();
1716 XmlSchemaParticle parciele;
1719 public XsdValidityState (XmlSchemaParticle particle)
1721 this.parciele = particle;
1722 currentParticles.Add (particle);