// Read a doctype declaration. // // Already read: '<!DOCTYPE' public void Read() { // turn off pe scanning input.ScanForPE = false; // require whitespace, then read the name if (!input.SkipWhitespace()) { Error(/* TODO */); } context.DocTypeName = input.ReadName(); // value of internal subset defaults to empty context.InternalSubset = String.Empty; // values of the public and system ids default to empty context.PublicId = String.Empty; context.SystemId = String.Empty; // check for an external id bool hasWS = input.SkipWhitespace(); if (!input.PeekChar()) { Error("Xml_UnexpectedEOF"); } if (input.peekChar == 'S' || input.peekChar == 'P') { // external id must be preceded by whitespace if (!hasWS) { Error(/* TODO */); } // allow only an external id, not a public id ReadExternalOrPublicID(false, true); // skip potentially optional whitespace hasWS = input.SkipWhitespace(); // get the peekChar ready for internal subset check if (!input.PeekChar()) { Error("Xml_UnexpectedEOF"); } } // check for an internal subset if (input.peekChar == '[') { // internal subset must be preceded by whitespace if (!hasWS) { Error(/* TODO */); } // move input to '[' input.NextChar(); // push the internal subset log onto the log stack input.Logger.Push(new StringBuilder()); // read the internal subset ReadInternalSubset(); // get the internal subset from the log and pop it from the logger context.InternalSubset = input.Logger.Pop().ToString(); // skip optional whitespace input.SkipWhitespace(); } // the dtd must end with '>' at this point input.Expect('>'); }