2009-11-10 27 views
9

Tôi đang sử dụng XmlSerializer để deserialize Xml achives. Nhưng tôi thấy lớp xsd.exe được tạo ra chỉ cung cấp khả năng đọc xml, nhưng không xác nhận. Ví dụ, nếu một nút bị thiếu trong một tài liệu, trường thuộc tính của lớp được tạo sẽ là null, thay vì ném một ngoại lệ xác nhận như tôi mong đợi. Làm thế nào tôi có thể đạt được điều đó? Cảm ơn!xmlserializer validation

Trả lời

26

Mã sau đây nên xác thực đối với giản đồ trong khi deserializing. Mã tương tự có thể được sử dụng để xác nhận hợp lệ đối với một lược đồ trong khi tuần tự hóa.

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

Cảm ơn bạn đã chia sẻ giải pháp này. Vì điều này đặt xác nhận hợp lệ với việc deserialize bằng cách xác thực thông qua XmlReader, nó là một cách tiếp cận tốt hơn. – el2iot2

4

Mã sau sẽ tải và xác thực XML theo cách thủ công đối với tệp lược đồ theo chương trình, cho phép bạn xử lý bất kỳ resulting errors and/or warnings nào.

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

Bây giờ rõ ràng là bạn mong muốn có các lớp học được tạo ra bởi xsd.exe để làm điều này tự động và trong khi tải (phương pháp trên sẽ đòi hỏi phải có xử lý thứ hai của tập tin XML), nhưng một Validate pre-load sẽ cho phép bạn lập trình phát hiện tệp đầu vào không đúng định dạng.

+0

@John Saunders - Tôi nghi ngờ rằng mã tạo lớp có thể sẽ thay đổi hoạt động của mình bất kỳ lúc nào và trang web msdn không hiển thị tùy chọn thích hợp cho xsd.exe, vì vậy tôi cho rằng workaround ... – el2iot2

+1

Trong văn bản câu hỏi, OP thể hiện rằng anh ta muốn một ngoại lệ được ném cho một xml đầu vào không hợp lệ. Cách tiếp cận này thực hiện điều đó. Tôi không tuyên bố rằng đây là cách duy nhất nó có thể được thực hiện, hoặc thậm chí đó là cách tốt nhất. Nhưng tôi đã phản ứng với một cách tiếp cận (ngoài đỉnh đầu của tôi) mà tôi đã sử dụng trong quá khứ để xác nhận hợp lệ các tài liệu XML. – el2iot2