6

I know I can validate xml against a schema using a callback method like the following, but is there a way that I can do it synchronously instead of event driven?

One way I thought of would be to set a class member boolean flag IsValidated=false then
call xml.Validate(ValidationEventHandler). The event handler would set IsValidated=true once it's finished. In the mean time, do a loop checking until the flag is set to true then continue.

This is for .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, I have done a test and it appears that xml.validate actually waits until the callback has completed before new code is executed.

In the following example, the MessageBox.Show("After Validate"); always happens after the execution of myValidationEventHandler.

I also stepped through the code to verify this.

So I guess that makes my question a non issue.

// 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
    }
M3NTA7
  • 1,307
  • 1
  • 13
  • 25
  • 1
    I think you have made a typo, you mean "do it asynchronously" instead of "do it synchronously", don't you? – ggPeti Oct 10 '11 at 21:42
  • 1
    I don't get what you mean. This _is_ synchronous. And the `ValidationEventHandler` is called synchronously when an error or warning is found. What do you want instead? – John Saunders Oct 10 '11 at 23:25
  • By synchronous, I mean that I don't want to continue until I know if an error is found or not because I want to base subsequent logic on whether there were errors or not. With the event handler, I don't know when the event may fire, therefore I need to wait until it fires before continuing. – M3NTA7 Oct 11 '11 at 16:11
  • Vote up from me for confirming that XmlDocument.Validate is a synchronous call. I think he validation event is a little bit misleading here. – anhoppe Feb 26 '16 at 12:37

4 Answers4

6

You can specify null for the ValidationEventHandler to have the Validate method throw an exception.

    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;
    }
Timiz0r
  • 1,304
  • 7
  • 7
1

Use a ManualResetEventSlim.

Set() the event in the callback, and WaitOne() after calling Validate().

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • That's the direction I was looking for. That or even something without events ideally. Basically, I just want to hang around until the validation is complete. Another note, I'm using .NET 3.5 sorry I didn't mention that. I'll update my question. – M3NTA7 Oct 10 '11 at 22:46
  • Just remove `Slim` to use the older, slower version. – SLaks Oct 10 '11 at 22:47
0

I think M3NTA7 is right that we're looking at this wrong when we worry about it being asynchronous.
Don't forget, you are not invoking Validate() in an asynchronous manner in the first place, so you aren't leaving the thread.

We pass the "validationCallback" address as a target so that we can customize the handling of any errors from validation.
But that process of calling the validation callback delegate all happens I believe synchronously inside the synchronous call to Validate(). :)

So it will all be done when Validate() returns.

Mike M
  • 1,382
  • 11
  • 23
-4

I would pass in a function that does what you need it to do if Valid, this would then call back to that once its finished validation correctly.

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();
    }
Jake Kalstad
  • 2,045
  • 14
  • 20