namespace Mono.Xml.Schema
{
- internal enum XsdParticleEvaluationResult
- {
- Matched = 1, // Matched one of its components.
- Passed = 2, // Did not match, but it successfully passed the whole components.
- InvalidIncomplete = 3, // It had incomplete validation state, and in fact it failed to pass.
- Mismatched = 4 // Dis not match,
- }
-
- internal class XsdValidationStateManager
+ internal class XsdParticleStateManager
{
Hashtable table;
- XmlSchemaElement currentElement;
XmlSchemaContentProcessing processContents;
- public XsdValidationStateManager ()
+ public XsdParticleStateManager ()
{
table = new Hashtable ();
processContents = XmlSchemaContentProcessing.Strict; // not Lax
}
- public XmlSchemaElement CurrentElement {
- get { return currentElement; }
- set { currentElement = value; }
+ public XmlSchemaElement CurrentElement;
+
+ public Stack ContextStack = new Stack ();
+
+ public XsdValidationContext Context
+ = new XsdValidationContext ();
+
+ public XmlSchemaContentProcessing ProcessContents {
+ get { return processContents; }
}
- internal void SetCurrentElement (XmlSchemaElement elt)
+ public void PushContext ()
{
- this.currentElement = elt;
+ ContextStack.Push (Context.Clone ());
}
- public XmlSchemaContentProcessing ProcessContents {
- get { return processContents; }
+ public void PopContext ()
+ {
+ Context = (XsdValidationContext) ContextStack.Pop ();
}
internal void SetProcessContents (XmlSchemaContentProcessing value)
// Dynamic members
int occured;
- string message;
- XsdValidationStateManager manager;
+ readonly XsdParticleStateManager manager;
- public XsdValidationState (XsdValidationStateManager manager)
+ public XsdValidationState (XsdParticleStateManager manager)
{
this.manager = manager;
}
internal abstract bool EvaluateIsEmptiable ();
- public XsdValidationStateManager Manager {
- get { return manager; }
- }
-
- public string Message {
- get { return message; }
- }
+ public abstract void GetExpectedParticles (ArrayList al);
- public string MessageInternal {
- get { return message; }
- set { message = value; }
+ public XsdParticleStateManager Manager {
+ get { return manager; }
}
public int Occured {
internal class XsdElementValidationState : XsdValidationState
{
- public XsdElementValidationState (XmlSchemaElement element, XsdValidationStateManager manager)
+ public XsdElementValidationState (XmlSchemaElement element, XsdParticleStateManager manager)
: base (manager)
{
this.element = element;
- name = element.QualifiedName.Name;
- ns = element.QualifiedName.Namespace;
}
// final fields
- XmlSchemaElement element;
- string name;
- string ns;
+ readonly XmlSchemaElement element;
+
+ string Name {
+ get { return element.QualifiedName.Name; }
+ }
+
+ string NS {
+ get { return element.QualifiedName.Namespace; }
+ }
// Methods
-
+ public override void GetExpectedParticles (ArrayList al)
+ {
+ XmlSchemaElement copy = (XmlSchemaElement) MemberwiseClone ();
+ decimal mo = element.ValidatedMinOccurs - Occured;
+ copy.MinOccurs = mo > 0 ? mo : 0;
+ if (element.ValidatedMaxOccurs == decimal.MaxValue)
+ copy.MaxOccursString = "unbounded";
+ else
+ copy.MaxOccurs = element.ValidatedMaxOccurs - Occured;
+ al.Add (copy);
+ }
+
public override XsdValidationState EvaluateStartElement (string name, string ns)
{
- if (this.name == name && this.ns == ns && !element.IsAbstract) {
+ if (this.Name == name && this.NS == ns && !element.IsAbstract) {
return this.CheckOccurence (element);
} else {
for (int i = 0; i < element.SubstitutingElements.Count; i++) {
private XsdValidationState CheckOccurence (XmlSchemaElement maybeSubstituted)
{
OccuredInternal++;
- Manager.SetCurrentElement (maybeSubstituted);
+ Manager.CurrentElement = maybeSubstituted;
if (Occured > element.ValidatedMaxOccurs) {
- MessageInternal = "Element occurence excess.";
return XsdValidationState.Invalid;
} else if (Occured == element.ValidatedMaxOccurs) {
return Manager.Create (XmlSchemaParticle.Empty);
internal class XsdSequenceValidationState : XsdValidationState
{
- XmlSchemaSequence seq;
+ readonly XmlSchemaSequence seq;
int current;
XsdValidationState currentAutomata;
bool emptiable;
- decimal minOccurs;
- decimal maxOccurs;
- public XsdSequenceValidationState (XmlSchemaSequence sequence, XsdValidationStateManager manager)
- : this (sequence, manager, sequence.ValidatedMinOccurs, sequence.ValidatedMaxOccurs, -1)
+ public XsdSequenceValidationState (XmlSchemaSequence sequence, XsdParticleStateManager manager)
+ : base (manager)
{
+ seq = sequence;
+ this.current = -1;
}
- public XsdSequenceValidationState (XmlSchemaSequence sequence, XsdValidationStateManager manager,
- decimal minOccurs, decimal maxOccurs, int current)
- : base (manager)
+ public override void GetExpectedParticles (ArrayList al)
{
- seq = sequence;
- this.minOccurs = minOccurs;
- this.maxOccurs = maxOccurs;
- this.current = current;
+ // if not started, then just collect all items from seq.
+ if (currentAutomata == null) {
+ foreach (XmlSchemaParticle p in seq.CompiledItems) {
+ al.Add (p);
+ if (!p.ValidateIsEmptiable ())
+ break;
+ }
+ return;
+ }
+
+ // automata for ongoing iteration
+ if (currentAutomata != null) {
+ currentAutomata.GetExpectedParticles (al);
+ if (!currentAutomata.EvaluateIsEmptiable ())
+ return;
+
+ // remaining items after currentAutomata
+ for (int i = current + 1; i < seq.CompiledItems.Count; i++) {
+ XmlSchemaParticle p = seq.CompiledItems [i] as XmlSchemaParticle;
+ al.Add (p);
+ if (!p.ValidateIsEmptiable ())
+ break;
+ }
+ }
+
+ // itself
+ if (Occured + 1 == seq.ValidatedMaxOccurs)
+ return;
+
+ {
+ for (int i = 0; i <= current; i++)
+ al.Add (seq.CompiledItems [i]);
+ }
}
public override XsdValidationState EvaluateStartElement (string name, string ns)
}
if (xa is XsdEmptyValidationState &&
seq.CompiledItems.Count == idx + 1 &&
- Occured == maxOccurs) {
+ Occured == seq.ValidatedMaxOccurs) {
return XsdValidationState.Invalid;
} else {
XsdValidationState result = xa.EvaluateStartElement (name, ns);
currentAutomata = result;
if (increment) {
OccuredInternal++;
- if (Occured > maxOccurs)
+ if (Occured > seq.ValidatedMaxOccurs)
return XsdValidationState.Invalid;
}
// current++;
public override bool EvaluateEndElement ()
{
- if (minOccurs > Occured + 1)
+ if (seq.ValidatedMinOccurs > Occured + 1)
return false;
if (seq.CompiledItems.Count == 0)
return true;
- if (currentAutomata == null && minOccurs <= Occured)
+ if (currentAutomata == null && seq.ValidatedMinOccurs <= Occured)
return true;
int idx = current < 0 ? 0 : current;
if (current < 0)
OccuredInternal++;
- return minOccurs <= Occured && maxOccurs >= Occured;
+ return seq.ValidatedMinOccurs <= Occured && seq.ValidatedMaxOccurs >= Occured;
}
internal override bool EvaluateIsEmptiable ()\r
{\r
- if (minOccurs > Occured + 1)\r
+ if (seq.ValidatedMinOccurs > Occured + 1)\r
return false;\r
- if (minOccurs == 0 && currentAutomata == null)\r
+ if (seq.ValidatedMinOccurs == 0 && currentAutomata == null)\r
return true;\r
\r
if (emptiable)\r
internal class XsdChoiceValidationState : XsdValidationState
{
- XmlSchemaChoice choice;
+ readonly XmlSchemaChoice choice;
bool emptiable;
bool emptiableComputed;
- public XsdChoiceValidationState (XmlSchemaChoice choice, XsdValidationStateManager manager)
+ public XsdChoiceValidationState (XmlSchemaChoice choice, XsdParticleStateManager manager)
: base (manager)
{
this.choice = choice;
}
+ public override void GetExpectedParticles (ArrayList al)
+ {
+ if (Occured < choice.ValidatedMaxOccurs)
+ foreach (XmlSchemaParticle p in choice.CompiledItems)
+ al.Add (p);
+ }
+
public override XsdValidationState EvaluateStartElement (string localName, string ns)
{
emptiableComputed = false;
internal class XsdAllValidationState : XsdValidationState
{
- XmlSchemaAll all;
+ readonly XmlSchemaAll all;
ArrayList consumed = new ArrayList ();
- public XsdAllValidationState (XmlSchemaAll all, XsdValidationStateManager manager)
+ public XsdAllValidationState (XmlSchemaAll all, XsdParticleStateManager manager)
: base (manager)
{
this.all = all;
}
+ public override void GetExpectedParticles (ArrayList al)
+ {
+ foreach (XmlSchemaParticle p in all.CompiledItems)
+ if (!consumed.Contains (p))
+ al.Add (p);
+ }
+
public override XsdValidationState EvaluateStartElement (string localName, string ns)
{
if (all.CompiledItems.Count == 0)
if (consumed.Contains (xsElem))
return XsdValidationState.Invalid;
consumed.Add (xsElem);
- Manager.SetCurrentElement (xsElem);
+ Manager.CurrentElement = xsElem;
OccuredInternal = 1; // xs:all also occurs 0 or 1 always.
return this;
}
internal class XsdAnyValidationState : XsdValidationState
{
- XmlSchemaAny any;
+ readonly XmlSchemaAny any;
- public XsdAnyValidationState (XmlSchemaAny any, XsdValidationStateManager manager)
+ public XsdAnyValidationState (XmlSchemaAny any, XsdParticleStateManager manager)
: base (manager)
{
this.any = any;
}
// Methods
+ public override void GetExpectedParticles (ArrayList al)
+ {
+ al.Add (any);
+ }
+
public override XsdValidationState EvaluateStartElement (string name, string ns)
{
if (!MatchesNamespace (ns))
internal class XsdAppendedValidationState : XsdValidationState
{
- public XsdAppendedValidationState (XsdValidationStateManager manager,
+ public XsdAppendedValidationState (XsdParticleStateManager manager,
XsdValidationState head, XsdValidationState rest)
: base (manager)
{
XsdValidationState rest;
// Methods
+ public override void GetExpectedParticles (ArrayList al)
+ {
+ head.GetExpectedParticles (al);
+ rest.GetExpectedParticles (al);
+ }
+
public override XsdValidationState EvaluateStartElement (string name, string ns)
{
XsdValidationState afterHead = head.EvaluateStartElement (name, ns);
internal class XsdEmptyValidationState : XsdValidationState
{
- public XsdEmptyValidationState (XsdValidationStateManager manager)
+ public XsdEmptyValidationState (XsdParticleStateManager manager)
: base (manager)
{
}
// Methods
+
+ public override void GetExpectedParticles (ArrayList al)
+ {
+ // do nothing
+ }
+
public override XsdValidationState EvaluateStartElement (string name, string ns)
{
return XsdValidationState.Invalid;
internal class XsdInvalidValidationState : XsdValidationState
{
- internal XsdInvalidValidationState (XsdValidationStateManager manager)
+ internal XsdInvalidValidationState (XsdParticleStateManager manager)
: base (manager)
{
}
// Methods
+
+ public override void GetExpectedParticles (ArrayList al)
+ {
+ // do nothing
+ }
+
public override XsdValidationState EvaluateStartElement (string name, string ns)
{
return this;