2011-10-10 11 views
5

Sé que puedo validar xml contra un esquema utilizando un método de devolución de llamada como el siguiente, pero ¿hay alguna forma de que pueda hacerlo de forma síncrona en lugar de por evento?¿Validación del esquema XML síncrono? .NET 3.5

Una forma en que pensé sería establecer un indicador booleano miembro de clase IsValidated = falso luego
llamada xml.Validate (ValidationEventHandler). El controlador de eventos establecería IsValidated = true una vez que haya finalizado. Mientras tanto, haz una comprobación de bucle hasta que la bandera se establezca en verdadero y luego continúa.

Esto es para .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); 
    } 

Ok, he hecho una prueba y parece que en realidad xml.validate espera hasta que la devolución de llamada se ha completado antes de ejecutar el nuevo código.

En el siguiente ejemplo, MessageBox.Show ("Después de validar"); siempre ocurre después de la ejecución de myValidationEventHandler.

También revisé el código para verificar esto.

Supongo que eso hace que mi pregunta no sea un problema.

// 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

Creo que ha cometido un error tipográfico, quiere decir "hacerlo de forma asíncrona" en lugar de "hacerlo sincrónicamente", ¿no? – ggPeti

+1

No entiendo lo que quieres decir. Esto _es_ sincrónico. Y el 'ValidationEventHandler' se llama sincrónicamente cuando se encuentra un error o advertencia. ¿Qué quieres en cambio? –

+0

Por sincrónico, quiero decir que no quiero continuar hasta saber si se ha encontrado un error o no, porque quiero basar la lógica posterior en si hubo errores o no. Con el controlador de eventos, no sé cuándo se puede iniciar el evento, por lo tanto, debo esperar hasta que se dispare antes de continuar. – M3NTA7

Respuesta

1

Usa un ManualResetEventSlim.

Set() el evento en la devolución de llamada, y WaitOne() después de llamar al Validate().

+0

Esa es la dirección que estaba buscando.Eso o incluso algo sin eventos idealmente. Básicamente, solo quiero esperar hasta que se complete la validación. Otra nota, estoy usando .NET 3.5 lo siento, no lo mencioné. Actualizaré mi pregunta. – M3NTA7

+0

Simplemente elimine 'Slim' para usar la versión anterior, más lenta. – SLaks

-4

Me gustaría pasar en una función que hace lo que necesita hacer si es válida, esto devolvería la llamada una vez que su validación finalizó correctamente.

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

xml.Validate devuelve nulo. – M3NTA7

4

Puede especificar un valor nulo para el ValidationEventHandler que tiene el método Validar una excepción.

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; 
    } 
0

Creo que M3NTA7 tiene razón en que estamos viendo esto mal cuando nos preocupa que no sea asincrónico.
No olvide, no está invocando Validate() de manera asíncrona en primer lugar, por lo que no está dejando el hilo.

Pasamos la dirección "validationCallback" como destino para que podamos personalizar el manejo de cualquier error de validación.
Pero todo el proceso de invocar al delegado de devolución de llamada de validación ocurre Creo sincrónicamente dentro de la llamada síncrona a Validar(). :)

Todo se hará cuando Validate() regrese.