Как проверить документ XML на соответствие DTD в C#?

Я не хочу делать что-то необычное, я просто хочу убедиться, что документ действителен, и вывести сообщение об ошибке, если это не так. Google указал мне на это, но кажется, что XmlValidatingReader устарел (по крайней мере, так говорит мне MonoDevelop).

Редактировать: я пытаюсь дать совет Мердада, но у меня проблемы. Я думаю, что у меня есть большая часть этого, но я не могу найти OnValidationEvent нигде. Где я могу получить OnValidationEvent?

XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.DTD;
settings.ValidationEventHandler += new ValidationEventHandler(/*trouble is here*/);
XmlReader validatingReader = XmlReader.Create(fileToLoad, settings);

3 ответа

Решение

Вместо создания XmlValidatingReader класс, вы должны построить соответствующий XmlReaderSettings возразить и передать его в качестве аргумента XmlReader.Create метод:

var settings = new XmlReaderSettings { ValidationType = ValidationType.DTD };
settings.ValidationEventHandler += new ValidationEventHandler(OnValidationEvent);
var reader = XmlReader.Create("file.xml", settings);

Остальное без изменений.

PS OnValidationEvent Имя метода, который вы объявляете для обработки событий проверки. Очевидно, что вы можете удалить строку, если не хотите подписываться на события проверки, инициируемые XmlReader,

var messages = new StringBuilder();
var settings = new XmlReaderSettings { ValidationType = ValidationType.DTD };
settings.ValidationEventHandler += (sender, args) => messages.AppendLine(args.Message);
var reader = XmlReader.Create("file.xml", settings);

if (messages.Length > 0)
{
    // Log Validation Errors
    // Throw Exception
    // Etc.
}

ValidationEventHandler

Лямбда-выражения

Вывод типа

Я упомянул этот пример о проверке DTD. https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmlreadersettings.dtdprocessing?view=netcore-3.1

В этом примере неверный DTD XML, который я исправил, как показано ниже.

<!--XML file using a DTD-->
<!DOCTYPE store [
  <!ELEMENT store (item)*> 
  <!ELEMENT item (name,dept,price)>
  <!ATTLIST item type CDATA #REQUIRED ISBN CDATA 
#REQUIRED>
  <!ELEMENT name (#PCDATA)>
  <!ELEMENT dept (#PCDATA)>
  <!ELEMENT price (#PCDATA)>]>
<store>
  <item type="supplies"  ISBN="2-3631-4">
    <name>paint</name>
    <dept>1</dept>
    <price>16.95</price>
  </item>
</store>

Полное описание:

  1. В Visual Studio .NET создайте новый проект консольного приложения Visual C# с именем ValidateXml, Добавьте два оператора using в начало Class1.cs следующим образом:

    using System.Xml;        // for XmlTextReader and XmlValidatingReader
    using System.Xml.Schema; // for XmlSchemaCollection (which is used later)
    
  2. В Class1.cs, объявите логическую переменную с именем isValid до начала Main метод следующим образом:

    private static bool isValid = true;      // If a validation error occurs,
                                             // set this flag to false in the
                                             // validation event handler. 
    
  3. Создать XmlTextReader объект для чтения документа XML из текстового файла в Main метод, а затем создать XmlValidatingReader проверить эти данные XML следующим образом:

    XmlTextReader r = new XmlTextReader("C:\\MyFolder\\ProductWithDTD.xml");
    XmlValidatingReader v = new XmlValidatingReader(r);
    
  4. ValidationType собственность XmlValidatingReader Объект указывает тип требуемой проверки (DTD, XDR или Схема). Установите это свойство в DTD следующим образом:

    v.ValidationType = ValidationType.DTD;
    
  5. Если возникают какие-либо ошибки проверки, проверяющий считыватель генерирует событие проверки. Добавьте следующий код для регистрации обработчика события проверки (вы будете реализовывать MyValidationEventHandlerметод на шаге 7):

    v.ValidationEventHandler += 
       new ValidationEventHandler(MyValidationEventHandler);
    
  6. Добавьте следующий код, чтобы прочитать и проверить документ XML. Если возникают какие-либо ошибки проверки, MyValidationEventHandler вызывается для устранения ошибки. Этот метод устанавливает isValid ложно (см. шаг 8). Вы можете проверить статус isValid после проверки, чтобы увидеть, является ли документ действительным или недействительным.

    while (v.Read())
    {
       // Can add code here to process the content.
    }
    v.Close();
    
    // Check whether the document is valid or invalid.
    if (isValid)
       Console.WriteLine("Document is valid");
    else
       Console.WriteLine("Document is invalid");
    
  7. Написать MyValidationEventHandler метод после Main метод следующим образом:

    public static void MyValidationEventHandler(object sender, 
                                                ValidationEventArgs args) 
    {
       isValid = false;
       Console.WriteLine("Validation event\n" + args.Message);
    }
    

Создайте и запустите приложение. Приложение должно сообщить, что документ XML является действительным.Например: в Visual Studio .NET измените ProductWithDTD.xml сделать его недействительным (например, удалить <AuthorName>M soliman</AuthorName> элемент). Запустите приложение еще раз. Вы должны получить следующее сообщение об ошибке:

Validation event
Element 'Product' has invalid content. Expected 'ProductName'.
An error occurred at file:///C:/MyFolder/ProductWithDTD.xml(4, 5).
Document is invalid
Другие вопросы по тегам