【问题标题】:xmlserializer validationxmlserializer 验证
【发布时间】:2009-11-10 03:14:28
【问题描述】:

我正在使用 XmlSerializer 反序列化 Xml 档案。但我发现生成的类 xsd.exe 仅提供读取 xml 的功能,但没有验证。例如,如果文档中缺少一个节点,则生成的类的属性字段将为空,而不是像我预期的那样抛出验证异常。我怎样才能做到这一点?谢谢!

【问题讨论】:

    标签: c# xml-serialization xsd xsd.exe


    【解决方案1】:

    以下代码应在反序列化时针对架构进行验证。类似的代码可用于在序列化时针对模式进行验证。

    private static Response DeserializeAndValidate(string tempFileName)
    {
        XmlSchemaSet schemas = new XmlSchemaSet();
        schemas.Add(LoadSchema());
    
        Exception firstException = null;
    
        var settings = new XmlReaderSettings
                       {
                           Schemas = schemas,
                           ValidationType = ValidationType.Schema,
                           ValidationFlags =
                               XmlSchemaValidationFlags.ProcessIdentityConstraints |
                               XmlSchemaValidationFlags.ReportValidationWarnings
                       };
        settings.ValidationEventHandler +=
            delegate(object sender, ValidationEventArgs args)
            {
                if (args.Severity == XmlSeverityType.Warning)
                {
                    Console.WriteLine(args.Message);
                }
                else
                {
                    if (firstException == null)
                    {
                        firstException = args.Exception;
                    }
    
                    Console.WriteLine(args.Exception.ToString());
                }
            };
    
        Response result;
        using (var input = new StreamReader(tempFileName))
        {
            using (XmlReader reader = XmlReader.Create(input, settings))
            {
                XmlSerializer ser = new XmlSerializer(typeof (Response));
                result = (Response) ser.Deserialize(reader);
            }
        }
    
        if (firstException != null)
        {
            throw firstException;
        }
    
        return result;
    }
    

    【讨论】:

    • 感谢分享这个解决方案。由于这通过 XmlReader 验证使验证与反序列化保持一致,因此这是一种更好的方法。
    • 关于提示“类似代码可用于在序列化时再次验证模式”,这里有一个问题:stackoverflow.com/q/53168867/5333340
    【解决方案2】:

    以下代码将以编程方式手动加载并根据模式文件验证您的 XML,允许您处理任何resulting errors and/or warnings

    //Read in the schema document
    using (XmlReader schemaReader = XmlReader.Create("schema.xsd"))
    {
        XmlSchemaSet schemaSet = new XmlSchemaSet();
    
        //add the schema to the schema set
        schemaSet.Add(XmlSchema.Read(schemaReader, 
        new ValidationEventHandler(
            delegate(Object sender, ValidationEventArgs e)
            {
            }    
        )));
    
        //Load and validate against the programmatic schema set
        XmlDocument xmlDocument = new XmlDocument();
        xmlDocument.Schemas = schemaSet;
        xmlDocument.Load("something.xml");
    
        xmlDocument.Validate(new ValidationEventHandler(
            delegate(Object sender, ValidationEventArgs e)
            {
                //Report or respond to the error/warning
            }
        )); 
     }
    

    现在显然您希望 xsd.exe 生成的类在加载时自动执行此操作(上述方法需要对 XML 文件进行第二次处理),但预加载验证将允许您以编程方式检测格式错误的输入文件。

    【讨论】:

    • @John Saunders - 我怀疑类生成代码可能很快就会改变它的操作,而且 msdn 网站没有显示 xsd.exe 的相关选项,所以我认为这是合理的建议解决方法...
    • 在问题文本中,OP 表示他希望为无效的输入 xml 引发异常。这种方法确实做到了这一点。我并不是说这是可以做到的唯一方法,甚至不是最好的方法。但我用过去通常用来验证 XML 文档的方法(在我的脑海中)做出回应。
    猜你喜欢
    • 2011-01-25
    • 1970-01-01
    • 1970-01-01
    • 2017-06-27
    • 1970-01-01
    • 2023-01-08
    • 2011-09-16
    • 1970-01-01
    相关资源
    最近更新 更多