// Author: Dwivedi, Ajay kumar // Adwiv@Yahoo.com using System; using System.Collections; using System.Xml.Serialization; namespace System.Xml.Schema { /// /// Summary description for XmlSchemaParticle. /// public abstract class XmlSchemaParticle : XmlSchemaAnnotated { internal static XmlSchemaParticle Empty { get { if (empty == null) { empty = new EmptyParticle (); } return empty; } } decimal minOccurs, maxOccurs; string minstr, maxstr; static XmlSchemaParticle empty; decimal validatedMinOccurs = 1, validatedMaxOccurs = 1; internal int recursionDepth = -1; private decimal minEffectiveTotalRange = -1; internal bool parentIsGroupDefinition; protected XmlSchemaParticle() { minOccurs = decimal.One; maxOccurs = decimal.One; } #region Attributes [System.Xml.Serialization.XmlAttribute("minOccurs")] public string MinOccursString { get{ return minstr; } set { if (value == null) { minOccurs = decimal.One; minstr = value; return; } decimal val = decimal.Parse(value); if(val >= 0 && (val == Decimal.Truncate(val))) { minOccurs = val; minstr = val.ToString(); } else { throw new XmlSchemaException ("MinOccursString must be a non-negative number",null); } } } [System.Xml.Serialization.XmlAttribute("maxOccurs")] public string MaxOccursString { get{ return maxstr; } set { if(value == "unbounded") { maxstr = value; maxOccurs = decimal.MaxValue; } else { decimal val = decimal.Parse(value); if(val >= 0 && (val == Decimal.Truncate(val))) { maxOccurs = val; maxstr = val.ToString(); } else { throw new XmlSchemaException ("MaxOccurs must be a non-negative integer",null); } if (val == 0 && minstr == null) minOccurs = 0; } } } #endregion #region XmlIgnore [XmlIgnore] public decimal MinOccurs { get{ return minOccurs; } set { MinOccursString = value.ToString (); } } [XmlIgnore] public decimal MaxOccurs { get{ return maxOccurs; } set { MaxOccursString = value.ToString (); } } internal decimal ValidatedMinOccurs { get { return validatedMinOccurs; } } internal decimal ValidatedMaxOccurs { get { return validatedMaxOccurs; } } #endregion internal XmlSchemaParticle OptimizedParticle; internal abstract XmlSchemaParticle GetOptimizedParticle (bool isTop); internal XmlSchemaParticle GetShallowClone () { return (XmlSchemaParticle) MemberwiseClone (); } internal void CompileOccurence (ValidationEventHandler h, XmlSchema schema) { if (MinOccurs > MaxOccurs && !(MaxOccurs == 0 && MinOccursString == null)) error(h,"minOccurs must be less than or equal to maxOccurs"); else { if (MaxOccursString == "unbounded") this.validatedMaxOccurs = decimal.MaxValue; else this.validatedMaxOccurs = maxOccurs; if (this.validatedMaxOccurs == 0) this.validatedMinOccurs = 0; else this.validatedMinOccurs = minOccurs; } } internal override void CopyInfo (XmlSchemaParticle obj) { base.CopyInfo (obj); if (MaxOccursString == "unbounded") obj.maxOccurs = obj.validatedMaxOccurs = decimal.MaxValue; else obj.maxOccurs = obj.validatedMaxOccurs = this.ValidatedMaxOccurs; if (MaxOccurs == 0) obj.minOccurs = obj.validatedMinOccurs = 0; else obj.minOccurs = obj.validatedMinOccurs = this.ValidatedMinOccurs; if (MinOccursString != null) obj.MinOccursString = MinOccursString; if (MaxOccursString != null) obj.MaxOccursString = MaxOccursString; } internal virtual bool ValidateOccurenceRangeOK (XmlSchemaParticle other, ValidationEventHandler h, XmlSchema schema, bool raiseError) { if ((this.ValidatedMinOccurs < other.ValidatedMinOccurs) || (other.ValidatedMaxOccurs != decimal.MaxValue && this.ValidatedMaxOccurs > other.ValidatedMaxOccurs)) { if (raiseError) error (h, "Invalid derivation occurence range was found."); return false; } return true; } internal virtual decimal GetMinEffectiveTotalRange () { return ValidatedMinOccurs; } internal decimal GetMinEffectiveTotalRangeAllAndSequence () { if (minEffectiveTotalRange >= 0) return minEffectiveTotalRange; decimal product = 0; //this.ValidatedMinOccurs; XmlSchemaObjectCollection col = null; if (this is XmlSchemaAll) col = ((XmlSchemaAll) this).Items; else col = ((XmlSchemaSequence) this).Items; foreach (XmlSchemaParticle p in col) product += p.GetMinEffectiveTotalRange (); minEffectiveTotalRange = product; return product; } // 3.9.6 Particle Emptiable internal virtual bool ValidateIsEmptiable () { return this.validatedMinOccurs == 0 || this.GetMinEffectiveTotalRange () == 0; } internal abstract bool ValidateDerivationByRestriction (XmlSchemaParticle baseParticle, ValidationEventHandler h, XmlSchema schema, bool raiseError); internal abstract void ValidateUniqueParticleAttribution ( XmlSchemaObjectTable qnames, ArrayList nsNames, ValidationEventHandler h, XmlSchema schema); internal abstract void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels, ValidationEventHandler h, XmlSchema schema); // See http://www.thaiopensource.com/relaxng/simplify.html internal abstract void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema); internal abstract bool ParticleEquals (XmlSchemaParticle other); #region Internal Class internal class EmptyParticle : XmlSchemaParticle { internal EmptyParticle () { } internal override XmlSchemaParticle GetOptimizedParticle (bool isTop) { return this; } internal override bool ParticleEquals (XmlSchemaParticle other) { return other == this || other == XmlSchemaParticle.Empty; } internal override bool ValidateDerivationByRestriction (XmlSchemaParticle baseParticle, ValidationEventHandler h, XmlSchema schema, bool raiseError) { return true; } internal override void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema) { // do nothing } internal override void ValidateUniqueParticleAttribution (XmlSchemaObjectTable qnames, ArrayList nsNames, ValidationEventHandler h, XmlSchema schema) { // do nothing } internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels, ValidationEventHandler h, XmlSchema schema) { // do nothing } } #endregion } }