Синхронная проверка XML-схемы? .NET 3.5

#c# #xml #xsd #xsd-validation

#c# #xml #xsd #xsd-проверка

Вопрос:

Я знаю, что могу проверить xml на соответствие схеме, используя метод обратного вызова, подобный следующему, но есть ли способ, которым я могу сделать это синхронно, а не на основе событий?

Один из способов, о котором я подумал, — установить логический флаг члена класса isValidated=false, а затем
вызвать xml.Validate(ValidationEventHandler). Обработчик событий установит значение isValidated=true после его завершения. Тем временем выполняйте проверку цикла, пока флаг не будет установлен в значение true, затем продолжайте.

Это для .Net 3.5.

     public bool ValidateSchema(string xmlPath, string xsdPath)
    {
        XmlDocument xml = new XmlDocument();
        xml.Load(xmlPath);

        xml.Schemas.Add(null, xsdPath);

        xml.Validate(ValidationEventHandler); 
    }
  

Хорошо, я выполнил тест, и кажется, что xml.validate фактически ожидает завершения обратного вызова перед выполнением нового кода.

В следующем примере окно сообщения.Показать («После проверки»); всегда происходит после выполнения myValidationEventHandler .

Я также прошел через код, чтобы проверить это.

Так что, я думаю, это делает мой вопрос не проблемой.

 // load etc.
...

xmlValidate(myValidationEventHandler);

MessageBox.Show("After Validate");


    private void myValidationEventHandler(object sender, ValidationEventArgs e)
    {
        for (double i = 0; i < 100000; i  )
        {
            textBox1.Text = i.ToString();
            Application.DoEvents();
        }

    // do stuff with e
    }
  

Комментарии:

1. Я думаю, вы допустили опечатку, вы имеете в виду «делайте это асинхронно» вместо «делайте это синхронно», не так ли?

2. Я не понимаю, что вы имеете в виду. Это происходит синхронно. И ValidationEventHandler вызывается синхронно при обнаружении ошибки или предупреждения. Чего ты хочешь вместо этого?

3. Под синхронностью я подразумеваю, что я не хочу продолжать, пока не узнаю, найдена ошибка или нет, потому что я хочу основывать последующую логику на том, были ошибки или нет. С обработчиком событий я не знаю, когда событие может сработать, поэтому мне нужно подождать, пока оно сработает, прежде чем продолжить.

4. Проголосуйте от меня за подтверждение этого документа XmlDocument. Проверка — это синхронный вызов. Я думаю, что событие проверки здесь немного вводит в заблуждение.

Ответ №1:

Вы можете указать null для ValidationEventHandler, чтобы метод Validate выдавал исключение.

     public bool ValidateSchema(string xmlPath, string xsdPath)
    {
        XmlDocument xml = new XmlDocument();
        xml.Load(xmlPath);

        xml.Schemas.Add(null, xsdPath);

        try
        {
            xml.Validate(null);
        }
        catch (XmlSchemaValidationException)
        {
            return false;
        }
        return true;
    }
  

Ответ №2:

Используйте ManualResetEventSlim .

Set() событие при обратном вызове и WaitOne() после вызова Validate() .

Комментарии:

1. Это направление, которое я искал. Это или даже что-то без событий в идеале. В принципе, я просто хочу подождать, пока проверка не будет завершена. Еще одно замечание: я использую .NET 3.5, извините, я не упомянул об этом. Я обновлю свой вопрос.

2. Просто удалите Slim , чтобы использовать более старую, более медленную версию.

Ответ №3:

Я думаю, что M3NTA7 прав, что мы смотрим на это неправильно, когда беспокоимся о том, что это асинхронно.
Не забывайте, что вы не вызываете Validate() в первую очередь асинхронным образом, поэтому вы не покидаете поток.

Мы передаем адрес «validationCallback» в качестве целевого, чтобы мы могли настроить обработку любых ошибок при проверке.
Но я полагаю, что весь этот процесс вызова делегата обратного вызова проверки происходит синхронно внутри синхронного вызова Validate(). 🙂

Итак, все это будет сделано, когда Validate() вернется.

Ответ №4:

Я бы передал функцию, которая выполняет то, что вам нужно, если она действительна, затем она будет возвращена к ней после корректной завершения проверки.

 public void ValidateSchema(string xmlPath, string xsdPath, Action Success)
    {
        XmlDocument xml = new XmlDocument();
        xml.Load(xmlPath);

        xml.Schemas.Add(null, xsdPath);

        if( xml.Validate(ValidationEventHandler) ) Success();
    }