-->

Synchronous XML Schema Validation? .NET 3.5

2019-06-19 02:33发布

问题:

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
    }

回答1:

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


回答2:

Use a ManualResetEventSlim.

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



回答3:

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.



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