#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();
}