- // The reader is positioned on the head of the name.\r
- private DTDElementDeclaration ReadElementDecl ()\r
- {\r
- DTDElementDeclaration decl = new DTDElementDeclaration ();\r
- SkipWhitespace ();\r
- TryExpandPERef ();\r
- decl.Name = ReadName ();\r
- SkipWhitespace ();\r
- TryExpandPERef ();\r
- ReadContentSpec (decl);\r
- SkipWhitespace ();\r
- Expect ('>');\r
- return decl;\r
- }\r
-\r
- // read 'children'(BNF) of contentspec\r
- private void ReadContentSpec (DTDElementDeclaration decl)\r
- {\r
- switch(PeekChar ())\r
- {\r
- case 'E':\r
- decl.IsEmpty = true;\r
- Expect ("EMPTY");\r
- break;\r
- case 'A':\r
- decl.IsAny = true;\r
- Expect ("ANY");\r
- break;\r
- case '(':\r
- DTDContentModel model = decl.ContentModel;\r
- ReadChar ();\r
- SkipWhitespace ();\r
- TryExpandPERef ();\r
- if(PeekChar () == '#') {\r
- // Mixed Contents\r
- decl.IsMixedContent = true;\r
- Expect ("#PCDATA");\r
- SkipWhitespace ();\r
- TryExpandPERef ();\r
- SkipWhitespace ();\r
- while(PeekChar () != ')') {\r
- Expect('|');\r
- SkipWhitespace ();\r
- TryExpandPERef ();\r
- SkipWhitespace ();\r
- model.ChildModels.Add (ReadName ());\r
- SkipWhitespace ();\r
- TryExpandPERef ();\r
- }\r
- Expect (')');\r
- if(PeekChar () == '*')\r
- ReadChar (); // ZeroOrMore\r
- } else {\r
- // Non-Mixed Contents\r
- model.ChildModels.Add (ReadCP ());\r
- SkipWhitespace ();\r
-\r
- do { // copied from ReadCP() ...;-)\r
- TryExpandPERef ();\r
- SkipWhitespace ();\r
- if(PeekChar ()=='|') {\r
- // CPType=Or\r
- model.OrderType = DTDContentOrderType.Or;\r
- ReadChar ();\r
- SkipWhitespace ();\r
- model.ChildModels.Add (ReadCP ());\r
- SkipWhitespace ();\r
- }\r
- else if(PeekChar () == ',')\r
- {\r
- // CPType=Seq\r
- model.OrderType = DTDContentOrderType.Seq;\r
- ReadChar ();\r
- SkipWhitespace ();\r
- model.ChildModels.Add (ReadCP ());\r
- SkipWhitespace ();\r
- }\r
- else\r
- break;\r
- }\r
- while(true);\r
-\r
- Expect (')');\r
- switch(PeekChar ())\r
- {\r
- case '?':\r
- model.MinOccurs = 0;\r
- ReadChar ();\r
- break;\r
- case '*':\r
- model.MinOccurs = 0;\r
- model.MaxOccurs = decimal.MaxValue;\r
- ReadChar ();\r
- break;\r
- case '+':\r
- model.MaxOccurs = decimal.MaxValue;\r
- ReadChar ();\r
- break;\r
- }\r
- SkipWhitespace ();\r
- }\r
- SkipWhitespace ();\r
- break;\r
- }\r
- }\r
-\r
- // Read 'cp' (BNF) of contentdecl (BNF)\r
- private DTDContentModel ReadCP ()\r
- {\r
- DTDContentModel model = new DTDContentModel ();\r
- TryExpandPERef ();\r
- if(PeekChar () == '(') {\r
- ReadChar ();\r
- SkipWhitespace ();\r
- model.ChildModels.Add (ReadCP ());\r
- SkipWhitespace ();\r
- do {\r
- TryExpandPERef ();\r
- SkipWhitespace ();\r
- if(PeekChar ()=='|') {\r
- // CPType=Or\r
- model.OrderType = DTDContentOrderType.Or;\r
- ReadChar ();\r
- SkipWhitespace ();\r
- model.ChildModels.Add (ReadCP ());\r
- SkipWhitespace ();\r
- }\r
- else if(PeekChar () == ',') {\r
- // CPType=Seq\r
- model.OrderType = DTDContentOrderType.Seq;\r
- ReadChar ();\r
- SkipWhitespace ();\r
- model.ChildModels.Add (ReadCP ());\r
- SkipWhitespace ();\r
- }\r
- else\r
- break;\r
- }\r
- while(true);\r
- SkipWhitespace ();\r
- Expect (')');\r
- }\r
- else {\r
- TryExpandPERef ();\r
- model.ElementName = ReadName ();\r
- }\r
-\r
- switch(PeekChar ()) {\r
- case '?':\r
- model.MinOccurs = 0;\r
- ReadChar ();\r
- break;\r
- case '*':\r
- model.MinOccurs = 0;\r
- model.MaxOccurs = decimal.MaxValue;\r
- ReadChar ();\r
- break;\r
- case '+':\r
- model.MaxOccurs = decimal.MaxValue;\r
- ReadChar ();\r
- break;\r
- }\r
- return model;\r
- }\r
-\r
- // The reader is positioned on the first name char.\r
- private void ReadParameterEntityDecl ()\r
- {\r
- DTDParameterEntityDeclaration decl = \r
- new DTDParameterEntityDeclaration();\r
- decl.BaseURI = BaseURI;\r
-\r
- decl.Name = ReadName ();\r
- SkipWhitespace ();\r
-\r
- if (PeekChar () == 'S' || PeekChar () == 'P') {\r
-// throw new NotImplementedException ("External parameter entity reference is not implemented yet.");\r
- // read publicId/systemId\r
- ReadExternalID ();\r
- decl.PublicId = attributes ["PUBLIC"] as string;\r
- decl.SystemId = attributes ["SYSTEM"] as string;\r
- SkipWhitespace ();\r
- }\r
- else {\r
- TryExpandPERef ();\r
- int quoteChar = ReadChar ();\r
- int start = currentTag.Length;\r
- while (true) {\r
- SkipWhitespace ();\r
- int c = PeekChar ();\r
- if ((int) c == -1)\r
- throw new XmlException ("unexpected end of stream in entity value definition.");\r
- switch (c) {\r
- case '"':\r
- ReadChar ();\r
- if (quoteChar == '"') goto SKIP;\r
- break;\r
- case '\'':\r
- ReadChar ();\r
- if (quoteChar == '\'') goto SKIP;\r
- break;\r
- case '%':\r
- ImportAsPERef ();\r
- break;\r
- default:\r
- ReadChar ();\r
- break;\r
- }\r
- }\r
- SKIP:\r
- decl.Value = currentTag.ToString (start, currentTag.Length - start - 1);\r
- }\r
- SkipWhitespace ();\r
- Expect ('>');\r
- if (parameterEntities [decl.Name] == null) {\r
- parameterEntities.Add (decl.Name, decl);\r
- }\r
- }\r
-\r
- // reader is positioned on '%'\r
- private void ImportAsPERef ()\r
- {\r
- StringBuilder sb = null;\r
- int peRefStart = currentTag.Length;\r
- string appendStr = "";\r
- ReadChar ();\r
- string peName = ReadName ();\r
- Expect (';');\r
- DTDParameterEntityDeclaration peDecl =\r
- this.parameterEntities [peName] as DTDParameterEntityDeclaration;\r
- if (peDecl == null)\r
- throw ReaderError ("Parameter entity " + peName + " not found.");\r
- if (peDecl.SystemId != null) {\r
- pushParserInput (peDecl.SystemId);\r
- if (sb == null)\r
- sb = new StringBuilder ();\r
- else\r
- sb.Length = 0;\r
- while (PeekChar () != -1)\r
- sb.Append (ReadChar ());\r
- popParserInput ();\r
- appendStr = sb.ToString ();\r
- } else {\r
- appendStr = peDecl.Value;\r
- }\r
- currentTag.Remove (peRefStart,\r
- currentTag.Length - peRefStart);\r
- currentTag.Append (Dereference (appendStr));\r
- }\r
-\r
- // The reader is positioned on the head of the name.\r
- private DTDEntityDeclaration ReadEntityDecl ()\r
- {\r
- DTDEntityDeclaration decl = new DTDEntityDeclaration ();\r
- decl.Name = ReadName ();\r
- SkipWhitespace ();\r
- TryExpandPERef ();\r
- SkipWhitespace ();\r
-\r
- if (PeekChar () == 'S' || PeekChar () == 'P') {\r
- // external entity\r
- ReadExternalID ();\r
- decl.PublicId = attributes ["PUBLIC"] as string;\r
- decl.SystemId = attributes ["SYSTEM"] as string;\r
- SkipWhitespace ();\r
- if (PeekChar () == 'N')\r
- {\r
- // NDataDecl\r
- Expect ("NDATA");\r
- SkipWhitespace ();\r
- decl.NotationName = ReadName (); // ndata_name\r
- }\r
- }\r
- else {\r
- // general entity\r
- decl.EntityValue = ReadEntityValueDecl ();\r
- }\r
- SkipWhitespace ();\r
- Expect ('>');\r
- return decl;\r
- }\r
-\r
- private string ReadEntityValueDecl ()\r
- {\r
- SkipWhitespace ();\r
- // quotation char will be finally removed on unescaping\r
- int quoteChar = ReadChar ();\r
- int start = currentTag.Length;\r
- if (quoteChar != '\'' && quoteChar != '"')\r
- throw new XmlException ("quotation char was expected.");\r
-\r
- while (PeekChar () != quoteChar) {\r
- switch (PeekChar ()) {\r
- case '%':\r
- this.ImportAsPERef ();\r
- continue;\r
- case '&':\r
- ReadChar ();\r
-// Expect ('#');\r
-// ReadCharacterReference ();\r
- ReadReference (true);\r
- break;\r
- case -1:\r
- throw new XmlException ("unexpected end of stream.");\r
- default:\r
- ReadChar ();\r
- break;\r
- }\r
- }\r
- string value = Dereference (currentTag.ToString (start, currentTag.Length - start));\r
- Expect (quoteChar);\r
- return value;\r
- }\r
-\r
- private DTDAttListDeclaration ReadAttListDecl ()\r
- {\r
- SkipWhitespace ();\r
- TryExpandPERef ();\r
- string name = ReadName (); // target element name\r
- DTDAttListDeclaration decl =\r
- currentSubset.AttListDecls [name] as DTDAttListDeclaration;\r
- if (decl == null)\r
- decl = new DTDAttListDeclaration ();\r
- decl.Name = name;\r
-\r
- SkipWhitespace ();\r
- TryExpandPERef ();\r
- SkipWhitespace ();\r
-\r
- while (XmlConstructs.IsName ((char) PeekChar ())) {\r
- DTDAttributeDefinition def = ReadAttributeDefinition ();\r
- if (decl.AttributeDefinitions [def.Name] == null)\r
- decl.AttributeDefinitions.Add (def.Name, def);\r
- SkipWhitespace ();\r
- TryExpandPERef ();\r
- SkipWhitespace ();\r
- }\r
- SkipWhitespace ();\r
- Expect ('>');\r
- return decl;\r
- }\r
-\r
- private DTDAttributeDefinition ReadAttributeDefinition ()\r
- {\r
- DTDAttributeDefinition def = new DTDAttributeDefinition ();\r
-\r
- // attr_name\r
- TryExpandPERef ();\r
- def.Name = ReadName ();\r
- SkipWhitespace ();\r
-\r
- // attr_value\r
- TryExpandPERef ();\r
- switch(PeekChar ()) {\r
- case 'C': // CDATA\r
- Expect ("CDATA");\r
- def.AttributeType = DTDAttributeType.CData;\r
- break;\r
- case 'I': // ID, IDREF, IDREFS\r
- Expect ("ID");\r
- if(PeekChar () == 'R') {\r
- Expect ("REF");\r
- if(PeekChar () == 'S') {\r
- // IDREFS\r
- ReadChar ();\r
- def.AttributeType = DTDAttributeType.IdRefs;\r
- }\r
- else // IDREF\r
- def.AttributeType = DTDAttributeType.IdRef;\r
- }\r
- else // ID\r
- def.AttributeType = DTDAttributeType.Id;\r
- break;\r
- case 'E': // ENTITY, ENTITIES\r
- Expect ("ENTIT");\r
- switch(ReadChar ()) {\r
- case 'Y': // ENTITY\r
- def.AttributeType = DTDAttributeType.Entity;\r
- break;\r
- case 'I': // ENTITIES\r
- Expect ("ES");\r
- def.AttributeType = DTDAttributeType.Entities;\r
- break;\r
- }\r
- break;\r
- case 'N': // NMTOKEN, NMTOKENS, NOTATION\r
- ReadChar ();\r
- switch(PeekChar ()) {\r
- case 'M':\r
- Expect ("MTOKEN");\r
- if(PeekChar ()=='S') { // NMTOKENS\r
- ReadChar ();\r
- def.AttributeType = DTDAttributeType.NmTokens;\r
- }\r
- else // NMTOKEN\r
- def.AttributeType = DTDAttributeType.NmToken;\r
- break;\r
- case 'O':\r
- Expect ("OTATION");\r
- def.AttributeType = DTDAttributeType.Notation;\r
- SkipWhitespace ();\r
- Expect ('(');\r
- SkipWhitespace ();\r
- def.EnumeratedNotations.Add (ReadName ()); // notation name\r
- SkipWhitespace ();\r
- while(PeekChar () == '|') {\r
- ReadChar ();\r
- SkipWhitespace ();\r
- def.EnumeratedNotations.Add (ReadName ()); // notation name\r
- SkipWhitespace ();\r
- }\r
- Expect (')');\r
- break;\r
- default:\r
- throw new XmlException ("attribute declaration syntax error.");\r
- }\r
- break;\r
- default: // Enumerated Values\r
- TryExpandPERef ();\r
- Expect ('(');\r
- SkipWhitespace ();\r
- def.EnumeratedAttributeDeclaration.Add (ReadNmToken ()); // enum value\r
- SkipWhitespace ();\r
- while(PeekChar () == '|') {\r
- ReadChar ();\r
- SkipWhitespace ();\r
- def.EnumeratedAttributeDeclaration.Add (ReadNmToken ()); // enum value\r
- SkipWhitespace ();\r
- }\r
- Expect (')');\r
- break;\r
- }\r
- SkipWhitespace ();\r
-\r
- TryExpandPERef ();\r
-\r
- // def_value\r
- if(PeekChar () == '#')\r
- {\r
- ReadChar ();\r
- switch(PeekChar ())\r
- {\r
- case 'R':\r
- Expect ("REQUIRED");\r
- def.OccurenceType = DTDAttributeOccurenceType.Required;\r
- break;\r
- case 'I':\r
- Expect ("IMPLIED");\r
- def.OccurenceType = DTDAttributeOccurenceType.Optional;\r
- break;\r
- case 'F':\r
- Expect ("FIXED");\r
- def.OccurenceType = DTDAttributeOccurenceType.Fixed;\r
- SkipWhitespace ();\r
- def.UnresolvedDefaultValue = ReadAttribute ();\r
- break;\r
- }\r
- } else {\r
- // one of the enumerated value\r
- if (PeekChar () == -1) {\r
- popParserInput ();\r
- }\r
- SkipWhitespace ();\r
- def.UnresolvedDefaultValue = ReadAttribute ();\r
- }\r
-\r
- return def;\r
- }\r
-\r
- private DTDNotationDeclaration ReadNotationDecl()\r
- {\r
- DTDNotationDeclaration decl = new DTDNotationDeclaration ();\r
- SkipWhitespace ();\r
- decl.Name = ReadName (); // notation name\r
- if (namespaces) { // copy from SetProperties ;-)
- int indexOfColon = decl.Name.IndexOf (':');
-
- if (indexOfColon == -1) {
- decl.Prefix = String.Empty;
- decl.LocalName = decl.Name;
- } else {
- decl.Prefix = decl.Name.Substring (0, indexOfColon);
- decl.LocalName = decl.Name.Substring (indexOfColon + 1);
- }
- } else {
- decl.Prefix = String.Empty;
- decl.LocalName = decl.Name;
- }
-\r
- SkipWhitespace ();\r
- if(PeekChar () == 'P') {\r
- decl.PublicId = ReadPubidLiteral ();\r
- SkipWhitespace ();\r
- if (PeekChar () == '\'' || PeekChar () == '"') {\r
- decl.SystemId = ReadSystemLiteral (false);\r
- SkipWhitespace ();\r
- }\r
- } else if(PeekChar () == 'S') {\r
- decl.SystemId = ReadSystemLiteral (true);\r
- SkipWhitespace ();\r
- }\r
- if(decl.PublicId == null && decl.SystemId == null)\r
- throw new XmlException ("public or system declaration required for \"NOTATION\" declaration.");\r
- Expect ('>');\r
- return decl;\r
- }\r
-\r
- private void TryExpandPERef ()\r
- {\r
- if (PeekChar () == '%') {\r
- ReadChar ();\r
- if (!XmlConstructs.IsName (PeekChar ()))\r
- return;\r
- ExpandPERef ();\r
- }\r
- }\r
-\r
- // reader is positioned on the first letter of the name.\r
- private void ExpandPERef ()\r
- {\r
- ExpandPERef (true);\r
- }\r
-\r
- private void ExpandPERef (bool attachSpace)\r
- {\r
- string peName = ReadName ();\r
- Expect (";");\r
- ExpandNamedPERef (peName, attachSpace);\r
- }\r
-\r
- private void ExpandNamedPERef (string peName, bool attachSpace)\r
- {\r
- DTDParameterEntityDeclaration decl =\r
- parameterEntities [peName] as DTDParameterEntityDeclaration;\r
- if (decl == null)\r
- throw new XmlException ("undeclared parameter entity: '" + peName + "'");\r
- if (decl.SystemId != null) {\r
- pushParserInput (decl.SystemId);\r
- }\r
- // add buffer\r
- else\r
- currentInput.InsertParameterEntityBuffer (attachSpace ? " " + Dereference (decl.Value) + " " : decl.Value);\r
- SkipWhitespace (); // is it ok?\r
-// while (PeekChar () == '%')\r
-// TryExpandPERef (); // recursive\r
- }\r
-\r
- private void ReadExternalID() {\r
- switch(PeekChar ()) {\r
- case 'S':\r
- attributes ["PUBLIC"] = null;\r
- attributes ["SYSTEM"] = ReadSystemLiteral (true);\r
- break;\r
- case 'P':\r
- attributes ["PUBLIC"] = ReadPubidLiteral ();\r
- SkipWhitespace ();\r
- attributes ["SYSTEM"] = ReadSystemLiteral (false);\r
- break;\r
- }\r
- }\r
-