// Read 'cp' (BNF) of contentdecl (BNF) private DTDContentModel ReadCP (DTDElementDeclaration elem) { DTDContentModel model = null; TryExpandPERef (); if(PeekChar () == '(') { model = new DTDContentModel (DTD, elem.Name); ReadChar (); SkipWhitespace (); model.ChildModels.Add (ReadCP (elem)); SkipWhitespace (); do { if (PeekChar () == '%') { TryExpandPERef (); continue; } if(PeekChar ()=='|') { // CPType=Or if (model.OrderType == DTDContentOrderType.Seq) throw NotWFError ("Inconsistent choice markup in sequence cp."); model.OrderType = DTDContentOrderType.Or; ReadChar (); SkipWhitespace (); AddContentModel (model.ChildModels, ReadCP (elem)); SkipWhitespace (); } else if(PeekChar () == ',') { // CPType=Seq if (model.OrderType == DTDContentOrderType.Or) throw NotWFError ("Inconsistent sequence markup in choice cp."); model.OrderType = DTDContentOrderType.Seq; ReadChar (); SkipWhitespace (); model.ChildModels.Add (ReadCP (elem)); SkipWhitespace (); } else break; } while(true); ExpectAfterWhitespace (')'); } else { TryExpandPERef (); model = new DTDContentModel (DTD, elem.Name); model.ElementName = ReadName (); } switch(PeekChar ()) { case '?': model.Occurence = DTDOccurence.Optional; ReadChar (); break; case '*': model.Occurence = DTDOccurence.ZeroOrMore; ReadChar (); break; case '+': model.Occurence = DTDOccurence.OneOrMore; ReadChar (); break; } return model; }
private void AddContentModel (DTDContentModelCollection cmc, DTDContentModel cm) { if (cm.ElementName != null) { for (int i = 0; i < cmc.Count; i++) { if (cmc [i].ElementName == cm.ElementName) { HandleError (new XmlSchemaException ("Element content must be unique inside mixed content model.", this.LineNumber, this.LinePosition, null, this.BaseURI, null)); return; } } } cmc.Add (cm); }
// read 'children'(BNF) of contentspec private void ReadContentSpec (DTDElementDeclaration decl) { TryExpandPERef (); switch(ReadChar ()) { case 'E': decl.IsEmpty = true; Expect ("MPTY"); break; case 'A': decl.IsAny = true; Expect ("NY"); break; case '(': DTDContentModel model = decl.ContentModel; SkipWhitespace (); TryExpandPERef (); if(PeekChar () == '#') { // Mixed Contents. "#PCDATA" must appear first. decl.IsMixedContent = true; model.Occurence = DTDOccurence.ZeroOrMore; model.OrderType = DTDContentOrderType.Or; Expect ("#PCDATA"); SkipWhitespace (); TryExpandPERef (); while(PeekChar () != ')') { SkipWhitespace (); if (PeekChar () == '%') { TryExpandPERef (); continue; } Expect('|'); SkipWhitespace (); TryExpandPERef (); DTDContentModel elem = new DTDContentModel (DTD, decl.Name); // elem.LineNumber = currentInput.LineNumber; // elem.LinePosition = currentInput.LinePosition; elem.ElementName = ReadName (); this.AddContentModel (model.ChildModels, elem); SkipWhitespace (); TryExpandPERef (); } Expect (')'); if (model.ChildModels.Count > 0) Expect ('*'); else if (PeekChar () == '*') Expect ('*'); } else { // Non-Mixed Contents model.ChildModels.Add (ReadCP (decl)); SkipWhitespace (); do { // copied from ReadCP() ...;-) if (PeekChar () == '%') { TryExpandPERef (); continue; } if(PeekChar ()=='|') { // CPType=Or if (model.OrderType == DTDContentOrderType.Seq) throw NotWFError ("Inconsistent choice markup in sequence cp."); model.OrderType = DTDContentOrderType.Or; ReadChar (); SkipWhitespace (); AddContentModel (model.ChildModels, ReadCP (decl)); SkipWhitespace (); } else if(PeekChar () == ',') { // CPType=Seq if (model.OrderType == DTDContentOrderType.Or) throw NotWFError ("Inconsistent sequence markup in choice cp."); model.OrderType = DTDContentOrderType.Seq; ReadChar (); SkipWhitespace (); model.ChildModels.Add (ReadCP (decl)); SkipWhitespace (); } else break; } while(true); Expect (')'); switch(PeekChar ()) { case '?': model.Occurence = DTDOccurence.Optional; ReadChar (); break; case '*': model.Occurence = DTDOccurence.ZeroOrMore; ReadChar (); break; case '+': model.Occurence = DTDOccurence.OneOrMore; ReadChar (); break; } SkipWhitespace (); } SkipWhitespace (); break; default: throw NotWFError ("ContentSpec is missing."); } }