private void CompileContentModel(CompiledContentModel compiledContentModel, XmlSchemaParticle particle) { if (particle is XmlSchemaElement) { compiledContentModel.AddTerminal(((XmlSchemaElement)particle).QualifiedName, null, this.validationEventHandler); } else if (particle is XmlSchemaAny) { compiledContentModel.AddAny((XmlSchemaAny)particle); } else if (particle is XmlSchemaGroupRef) { XmlSchemaParticle realParticle = ((XmlSchemaGroupRef)particle).Particle; Debug.Assert(realParticle != null && !realParticle.IsEmpty); compiledContentModel.OpenGroup(); CompileContentModel(compiledContentModel, realParticle); compiledContentModel.CloseGroup(); } else if (particle is XmlSchemaAll) { XmlSchemaAll all = (XmlSchemaAll)particle; compiledContentModel.StartAllElements(all.Items.Count); foreach (XmlSchemaElement localElement in all.Items) { if (!compiledContentModel.AddAllElement(localElement.QualifiedName, (all.MinOccurs == decimal.One ? localElement.MinOccurs == decimal.One : false))) { SendValidationEvent(Res.Sch_DupElement, localElement.QualifiedName.ToString(), localElement); } } } else if (particle is XmlSchemaGroupBase) { XmlSchemaObjectCollection particles = ((XmlSchemaGroupBase)particle).Items; bool isChoice = particle is XmlSchemaChoice; compiledContentModel.OpenGroup(); bool first = true; foreach (XmlSchemaParticle p in particles) { if (first) { first = false; } else if (isChoice) { compiledContentModel.AddChoice(); } else { compiledContentModel.AddSequence(); } Debug.Assert(!p.IsEmpty); CompileContentModel(compiledContentModel, p); } compiledContentModel.CloseGroup(); } else { Debug.Assert(false); } if (particle.MinOccurs == decimal.One && particle.MaxOccurs == decimal.One) { // nothing } else if (particle.MinOccurs == decimal.Zero && particle.MaxOccurs == decimal.One) { compiledContentModel.QuestionMark(); } else if (particle.MinOccurs == decimal.Zero && particle.MaxOccurs == decimal.MaxValue) { compiledContentModel.Star(); } else if (particle.MinOccurs == decimal.One && particle.MaxOccurs == decimal.MaxValue) { compiledContentModel.Plus(); } else { compiledContentModel.MinMax(particle.MinOccurs, particle.MaxOccurs); } }
private void ParseElementDecl() { XmlQualifiedName name = XmlQualifiedName.Empty; while (true) { switch (_SubState) { case 0: _HasSeenWhiteSpace = false; GetToken(); name = GetName(_Token, _Namespaces); _ElementDecl = (SchemaElementDecl)_SchemaInfo.ElementDecls[name]; if (_ElementDecl != null) { SendValidationEvent(Res.Sch_DupElementDecl, _Scanner.GetText()); } else { _ElementDecl = (SchemaElementDecl)_UndeclaredElements[name]; if (_ElementDecl != null) { _UndeclaredElements.Remove(name); } else { _ElementDecl = new SchemaElementDecl(name, name.Namespace, SchemaType.DTD, _SchemaNames); } _SchemaInfo.ElementDecls.Add(name, _ElementDecl); } _ElementDecl.IsDeclaredInExternal = !_IsInternal; _SubState = 1; break; case 1: if (!_HasSeenWhiteSpace) { SkipWhitespace(true); } _SubState = 2; break; case 2: GetToken(); _ContentModel = _ElementDecl.Content; if (_Token == XmlToken.NAME) { if (_Scanner.IsToken(XmlToken.ANY)) { _ContentModel.ContentType = CompiledContentModel.Type.Any; _SubState = 12; } else if (_Scanner.IsToken(XmlToken.EMPTY)) { _ContentModel.ContentType = CompiledContentModel.Type.Empty; _SubState = 12; } else { _SubState = 15; // error; } } else if (_Token == XmlToken.LPAREN) { _ContentModel.Start(); _ContentModel.OpenGroup(); PushGroup(); _SubState = 3; _L = 0; _HasTerminal = false; } else { _SubState = 15; // error } break; case 3: GetToken(); if (_Token == XmlToken.HASH) { _SubState = 4; } else { _ContentModel.ContentType = CompiledContentModel.Type.ElementOnly; _HasTerminal = false; _SubState = 13; Push(DtdFunctionIndex.ParseElementContent); ParseElementContent(); } break; case 4: _HasSeenWhiteSpace = SkipWhitespace(false); _SubState = 5; break; case 5: GetToken(); if (_HasSeenWhiteSpace || !_Scanner.IsToken(XmlToken.PCDATA)) throw new XmlException(Res.Xml_ExpectPcData, _Scanner.StartLineNum, _Scanner.StartLinePos); _ContentModel.AddTerminal( _SchemaNames.QnPCData, null, _InternalValidationEventHandler); _HasTerminal = true; _SubState = 6; break; case 6: _HasSeenWhiteSpace = false; GetToken(); if (_Token == XmlToken.RPAREN) { _ContentModel.ContentType = CompiledContentModel.Type.Text; _ContentModel.CloseGroup(); _ContentModel.Finish(_InternalValidationEventHandler, true); PopGroup(); _L = -1; _SubState = 14; _HasSeenWhiteSpace = false; } else { _ContentModel.ContentType = CompiledContentModel.Type.Mixed; _SubState = 7; } break; case 7: if (_Token == XmlToken.OR) { _ContentModel.AddChoice(); _HasTerminal = false; _SubState = 8; } else if (_Token == XmlToken.RPAREN) { PopGroup(); _L = -1; _HasSeenWhiteSpace = false; _SubState = 10; } else { _SubState = 15; // error } break; case 8: GetToken(); _ContentModel.AddTerminal(GetName(_Token, _Namespaces), _Prefix, _InternalValidationEventHandler); _HasTerminal = true; _SubState = 9; break; case 9: _HasSeenWhiteSpace = false; GetToken(); _SubState = 7; break; case 10: if (!_HasSeenWhiteSpace) { _HasSeenWhiteSpace = SkipWhitespace(false); } _SubState = 11; break; case 11: GetToken(XmlToken.ASTERISK); if (_HasSeenWhiteSpace) throw new XmlException(Res.Xml_UnexpectedToken, "*", _Scanner.StartLineNum, _Scanner.StartLinePos); _ContentModel.CloseGroup(); _ContentModel.Star(); _ContentModel.Finish(_InternalValidationEventHandler, true); _SubState = 12; break; case 12: GetToken(); _SubState = 13; break; case 13: CheckTagend(_Token); Pop(); return; case 14: _HasSeenWhiteSpace = SkipWhitespace(false); GetToken(); if (_Token == XmlToken.ASTERISK) { if (_HasSeenWhiteSpace) throw new XmlException(Res.Xml_UnexpectedToken, "*", _Scanner.StartLineNum, _Scanner.StartLinePos); _SubState = 12; } else { _SubState = 13; } break; case 15: throw new XmlException(Res.Xml_InvalidContentModel, _Scanner.StartLineNum, _Scanner.StartLinePos); } // switch } // while }