2008-11-03 11 views
14

Tôi đang sử dụng XmlSerializer để viết và đọc một đối tượng để xml trong C#. Tôi hiện đang sử dụng các thuộc tính XmlElementXmlIgnore để thao tác tuần tự hóa đối tượng.Tôi có thể không deserialize với XmlSerializer trong C# nếu một phần tử không được tìm thấy?

Nếu tệp xml của tôi thiếu phần tử xml mà tôi yêu cầu, đối tượng của tôi vẫn còn deserializes (xml -> đối tượng) tốt. Làm cách nào để chỉ ra (tốt nhất là thông qua Thuộc tính) mà một trường nhất định là "bắt buộc"?

Dưới đây là một phương pháp mẫu của những gì tôi hiện đang sử dụng:

[XmlElement(ElementName="numberOfWidgets")] 
public int NumberThatIsRequired { 
    set ...; 
    get ...; 
} 

giải pháp lý tưởng của tôi sẽ có thêm một cái gì đó giống như một thuộc tính XmlRequired.

Ngoài ra, có một tham chiếu tốt cho những Thuộc tính có sẵn để điều khiển hành vi của XmlSerializer không?

+0

Câu hỏi msdn tương tự [tại đây] (http://social.msdn.microsoft.com/Forums/eu/xmlandnetfx/thread/a134471c-6b20-433e-8dd4-d153cac29810) cũng giải thích rằng xác thực là những gì bạn đang cố gắng để làm – KCD

+0

nếu bạn không có phần tử 'numberOfWidgets' trong XML, bạn sẽ có gì trong thuộc tính NumberThatIsRequired? số không? –

Trả lời

4

Tôi có câu trả lời cho phần thứ hai: "Attributes that control XML serialization".

Vẫn đang điều tra phần đầu tiên ...

EDIT: Tôi thật sự nghi ngờ bạn không thể thực hiện điều này thông qua việc tự deserialization XML. Tôi vừa chạy xsd.exe trên một lược đồ mẫu bao gồm một thuộc tính bắt buộc - và nó giống hệt nhau nếu thuộc tính được đánh dấu là tùy chọn. Nếu có một cách để yêu cầu các thuộc tính được thiết lập, tôi hy vọng nó sẽ được thực hiện trong trường hợp đó.

Tôi nghi ngờ về cơ bản bạn đã xác thực cây của đối tượng sau khi deserializing nó. Xin lỗi về điều đó ...

+0

Bạn cần phải có một không gian tên XML được thiết lập đúng trong XML nguồn của bạn cũng được tham chiếu trong XSD của bạn, hoặc xác thực bằng XSD sẽ không hoạt động đúng, bao gồm xác nhận trường bắt buộc. –

15

Cách duy nhất tôi tìm thấy để thực hiện việc này là thông qua XSD. Những gì bạn có thể làm là xác thực trong khi bạn deserialize:

static T Deserialize<T>(string xml, XmlSchemaSet schemas) 
{ 
    //List<XmlSchemaException> exceptions = new List<XmlSchemaException>(); 
    ValidationEventHandler validationHandler = (s, e) => 
    { 
     //you could alternatively catch all the exceptions 
     //exceptions.Add(e.Exception); 
     throw e.Exception; 
    }; 

    XmlReaderSettings settings = new XmlReaderSettings(); 
    settings.Schemas.Add(schemas); 
    settings.ValidationType = ValidationType.Schema; 
    settings.ValidationEventHandler += validationHandler; 

    XmlSerializer serializer = new XmlSerializer(typeof(T)); 
    using (StringReader sr = new StringReader(xml)) 
     using (XmlReader books = XmlReader.Create(sr, settings)) 
      return (T)serializer.Deserialize(books); 
} 
4

Vì lý do mở rộng, XmlSerializer là rất tha thứ khi nói đến deserialization; những thứ như [DefaultValue], ShouldSerialize{Foo}{Foo}Specifiedchủ yếu được sử dụng trongserialization (ngoại trừ {Foo}Specified, được thiết lập trong deserialization cũng như truy vấn trong serialization).

Như vậy; không có một cách dễ dàng để làm điều này, trừ khi bạn thực hiện IXmlSerializable và tự mình làm. affectednoob hiển thị tùy chọn xsd, cũng là tùy chọn.

+1

DefaultValue có ít nhất một hiệu ứng quan trọng trong quá trình deserialization. Nếu phần tử trống, không có DefaultValue thì có thể có lỗi phân tích cú pháp. Tuy nhiên, với nó, [mã được tạo] (http://msdn.microsoft.com/en-us/library/aa302290.aspx) sẽ bỏ qua phần tử trống. –