Wpf XmlDataProvider validation based on XSD schema

I'm writing C # (3.5 or 4 if I find the reason for this) WPF application that loads XAML snippets on the fly using a XamlReader to display a custom UI. This UI is bound to the XmlDataProvider before being shown and seems to work just fine.

I'm trying to figure out if it is possible for the datasource (XmlDataProvider that points to an XML document) to be automatically validated against the XSD document schema?

To clarify - I'm trying to avoid writing any custom validation rules due to the variability of the nature of the application. The XSD schema has constraints (such as regex or maximum length constraints) that I would like my UI to respond in the same way as the Winforms error provider.

Any help would be appreciated!

(No coincidence - would have tagged with XmlDataProvider, but could not create a new tag due to req's reputation)

+3


source to share


1 answer


I was working with a similar problem, loading XAML on the fly and validating user input. But in my situation I have a global DataContext

and all the download controls are bound to that context. When validation actions are performed, for example a custom button to "validate" the data is DataContext

serialized to XML and after that I used XSLT to get error tags from that XML, but I think you can use XSD if you can serialize DataContext

to that XSD.

My steps:



  • Loading Xaml and setting my object to container DataContext

    String xaml="some xaml";
    MyData myData=new MyData();
    TextReader textReader = new StringReader(CardContext.Xaml);
    XmlReader xmlReader = XmlReader.Create(textReader);
    //setting DataContext for panel named 'content'
    this.content.DataContext = myData;
    FrameworkElement myContent = (FrameworkElement) XamlReader.Load(xmlReader);
    this.content.Children.Clear();
    this.content.Children.Add(myContent);
    InitMyComponents(this.content);
    
          

  • Manages inside the xaml binding to the DataContext. DataContext is the MyData class. For example:

    public class MyData
    {
        IDictionary<String, MyControl> MyControls{get;set;}
        ....
    }
    
          

    Where

    class MyControl
    {
       String Id{get;set;}
       String Name{get;set;}
       String Value{get;set;}
    }
    
          

    Getting Bindings for Controls

    public static  Binding GetValueBinding(MyControl control)
    {
       Binding valueBinding = new Binding();
       valueBinding.Mode = BindingMode.TwoWay;
       valueBinding.Path = new PropertyPath("MyControls["+control.Id+"].Value");
       return valueBinding;
    }
    
          

  • The user works with the controls and changes some values.

  • When the user needs validation, I put the data into an XSD schema named MyMetaData (inside this schema, I have a MyControls table).

    MyMetaData _myMetaData;
    
    public void PushData(MyData myData)
        {
    
            foreach (MyControl control in myData.MyControls)
            {
             //fill table from xsd schema
       this._myMetaData.MyControls.AddMyControlsRow(control.Id,control.Name,control.Value);
    
    
            }
    
            this._myMetaData.AcceptChanges();
        }
    
          

  • Getting XML from DataTable

    this._myMetaData.MyControls.GetXml()
    
          

  • XML validation with xslt

    XslCompiledTransform xslCompiledTransform = new XslCompiledTransform(); 
    String xml = "some xml";
    TextReader textReader = new StringReader(xml );
    XmlReader xmlReader = XmlReader.Create(textReader);
    StringBuilder validationResult = new StringBuilder();
    XmlWriter xmlWriter = XmlWriter.Create(validationResult);
    //aply xslt (xslt return tags with error description and control Id)
    xslCompiledTransform.Transform(xmlReader, xmlWriter);
    //parsing result tags
    IList<ValidationError> parsedResult = ParseValidationResult(validationResult.ToString());
    
          

  • Find controls and runtime to display error information

    DependencyObject errorSource = LogicalTreeHelper.FindLogicalNode(this.content, error.Identifier);
    if (errorSource == null)
        return;
    if (errorSource is MyControl)
       (errorSource as MyControl).ShowErrorInfo(error.ErrorText);
    
          

This is my algorithm, but if you have some constraints on the XSD schema you will get errors in step 4 when you put the data into DataTable

.

+2


source







All Articles