XmlReader выдает несколько ошибок DTD

Допустим, мы хотим загрузить xml (cXML) и проверить его на соответствие DTD, который мы сохранили локально. Вот код для этого:

XmlPreloadedResolver resolver = new XmlPreloadedResolver(XmlKnownDtds.None);
resolver.Add(new Uri(DocTypeSystemId), File.ReadAllText(@"C:\cXml.dtd"));
XmlReaderSettings settings = new XmlReaderSettings
{
    ValidationType = ValidationType.DTD,
    DtdProcessing = DtdProcessing.Parse             
};
settings.ValidationEventHandler += Settings_ValidationEventHandler;

XmlParserContext context = new XmlParserContext(null, null, "cXML", null, 
                               DocTypeSystemId, null, null, null, XmlSpace.None);

XmlReader reader = XmlReader.Create(stream, settings, context);
XDocument doc = XDocument.Load(reader);

К сожалению, если входные данные cXML уже содержат определение DTD, XmlReader выдаст исключение XmlException с указанием: Message Cannot have multiple DTDs. Line 2, position 1.

Если мы удалим DOCTYPE из ввода, появится предупреждение No DTD found., а xml не будет проверен.

Кажется, что XmlReader с трудом использует XmlParserContext.


person Alex Kamburov    schedule 19.03.2014    source источник


Ответы (1)


Если вместо этого читатель является экземпляром устаревшего XmlTextReader:

XmlTextReader textReader = new XmlTextReader(stream, XmlNodeType.Document, context);
XmlValidatingReader reader = new XmlValidatingReader(textReader);
reader.ValidationType = ValidationType.DTD;
reader.ValidationEventHandler += Settings_ValidationEventHandler;

Тогда не будет исключений для нескольких DTD, и xml будет проверен.

Очевидно, что существует разница между функциями XmlTextReader и XmlReader. Они оба, кажется, выводят предупреждение, когда в xml отсутствует DOCTYPE, который останавливает проверку. Следующие вызовы связаны с неправильным пониманием XmlValidatingReaderImpl.ProcessCoreReaderEvent() и DtdValidator.Validate() (где schemaInfo.SchemaType == SchemaType.DTD является ложным, возможно, потому, что DTD не существует).

Имея все это в виду, кажется, лучше просто попытаться изменить/добавить элемент DOCTYPE во входной xml, чем бороться с XmlParserContext и различными реализациями чтения.

person Alex Kamburov    schedule 19.03.2014