基于 XSD 架构的 Wpf XmlDataProvider 验证

本文关键字:Wpf XmlDataProvider 验证 XSD 基于 | 更新日期: 2023-09-27 17:57:05

>我正在编写一个 c#(如果我找到原因,则为 3.5 或 4)WPF 应用程序,该应用程序使用 XamlReader 动态加载 XAML 片段以显示可自定义的 UI。此 UI 在显示之前绑定到 XmlDataProvider,并且似乎工作得很好。

我一直在尝试找出是否有可能让数据源(指向 XML 文档的 XmlDataProvider)根据文档的 XSD 架构自动验证?

澄清一下 - 由于应用程序的可变性,我试图避免编写任何自定义验证规则。XSD 架构指定了限制(例如正则表达式或最大长度约束),我希望我的 UI 以与 Winforms 错误提供程序类似的方式响应这些限制。

任何帮助将不胜感激!

(偶然 - 将使用 XmlDataProvider 标记,但由于信誉要求而无法创建新标记)

基于 XSD 架构的 Wpf XmlDataProvider 验证

我遇到了类似的问题:动态加载 XAML 并验证用户输入。但就我而言,我有一个全局DataContext,所有加载控件都绑定到该上下文。执行验证操作时,例如用户放置按钮"验证"数据,DataContext序列化为 XML,之后我使用 XSLT 从此 XML 获取错误标记,但我认为如果您可以为该 XSD 序列化DataContext,则可以使用 XSD。

我的步骤:

  1. 加载 Xaml 并将我的对象设置为容器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);
    
  2. xaml 内部的控件绑定到 DataContext。DataContext是这样的类MyData:

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

    哪里

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

    获取控件的绑定

    public static  Binding GetValueBinding(MyControl control)
    {
       Binding valueBinding = new Binding();
       valueBinding.Mode = BindingMode.TwoWay;
       valueBinding.Path = new PropertyPath("MyControls["+control.Id+"].Value");
       return valueBinding;
    }
    
  3. 用户使用控件并更改某些值。

  4. 当用户需要验证时,我将数据放入名为MyMetaData的XSD架构中(在该方案中,我有表MyControls)。

    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();
        }
    
  5. 从数据表获取 XML

    this._myMetaData.MyControls.GetXml()
    
  6. 使用 xslt 验证 XML

    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());
    
  7. 查找显示错误信息的控件和执行方法

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

这是我的算法,但是如果您对XSD架构有一些约束,则在将数据放入DataTable时,将在步骤4中出现错误。