2011-12-18 26 views
5

Tôi muốn XML được tạo bởi XmlSerializer để loại trừ các thuộc tính nếu chúng có giá trị mặc định. Điều này có thể với XmlSerializer hoặc tôi sẽ phải nhìn vào IXmlSerializable?Làm cách nào tôi có thể bỏ qua các thuộc tính theo giá trị của chúng bằng XmlSerializer

Ví dụ, tôi có thể có những lớp sau:

public class PositionedObject 
{ 
    public float X 
    { get; set; } 

    public float Y 
    { get; set;} 
} 

Tôi muốn nói với XmlSerializer rằng khi nó serializes một thể hiện của PositionedObject, để không bao gồm X nếu giá trị là 0 (và cùng với Y nếu nó là 0).

Trả lời

9

Chỉ cần khai báo một phương thức có tên ShouldSerializeX mà trả về true khi giá trị không phải là 0:

public bool ShouldSerializeX() 
{ 
    return X != 0; 
} 

Các serializer sẽ gọi phương pháp này để quyết định xem tài sản nên được tuần tự hay không.

+1

Câu trả lời này không đủ. Tôi không thấy làm thế nào serializer sẽ biết về một phương pháp như vậy. Và bên cạnh đó, điều này không thể mở rộng được. – Amy

+1

@Inuyasha, bạn đã thử chưa? Tôi biết nó hoạt động, tôi sử dụng giải pháp này nhiều lần. Nó không phải là tài liệu, nhưng nếu bạn nhìn vào mã serializer XML, bạn sẽ thấy rằng nó gọi phương thức này nếu nó tồn tại (cách khác, bạn cũng có thể tạo một thuộc tính chỉ đọc có tên là 'XSpecified', nó có cùng tác dụng). Và dù sao, bạn có biết một phương pháp có khả năng mở rộng hơn không? –

+0

Inuyasha - bạn có thực sự thử nó không? Dựa trên câu trả lời này tôi đã có thể Google một vài điều và tìm thấy một số bài báo tuyên bố rằng điều này sẽ làm việc. Tôi đang trong quá trình thực hiện ngay bây giờ. Dưới đây là một số thông tin khác: http://horacegoescoding.blogspot.com/2009/04/using-shouldserialize-for-conditional.html –

1

Lớp học của bạn có thể triển khai IXmlSerializable và trong phương thức WriteXml chọn không tuần tự hóa các thuộc tính có bất kỳ điều gì bạn cho là mặc định.

public class PositionedObject : IXmlSerializable 
{ 

    public void WriteXml(System.Xml.XmlWriter writer) 
    { 
     if ( Position != DefaultPosition) 
      writer.WriteAttributeString("Position", Position); 
    } 
} 

Ở vị trí của bạn là một cặp phao và bạn có thể phải sử dụng một số dung sai

+2

Nếu có thể tôi sẽ luôn luôn nói "không thực hiện IXmlSerializable", đặc biệt là cho deserialization - nó là hơi rải rác với bẫy ... Nếu có thể tôi sẽ luôn luôn đề nghị 1 kiểm tra XmlSerializer không hỗ trợ nó trực tiếp (như nó có trong trường hợp này) và thứ hai bằng cách sử dụng DTO phù hợp với XML, thay vì thực hiện quá phức tạp. –

0

cách Thomas' là cách đơn giản nhất để có thể những gì bạn muốn. Tuy nhiên, bạn có thể muốn xem xét rằng các kiểu giá trị kỹ thuật luôn có giá trị, và có lẽ bạn nên tuần tự hóa nó. Lưu ý rằng XmlSerializer sẽ bỏ qua việc thêm phần tử X nếu bạn khai báo nó là string hoặc loại tham chiếu khác.
Tất nhiên tuyên bố X phối hợp như chuỗi sẽ là ngớ ngẩn, nhưng bạn có thể khai báo nó là rỗng float?, sẽ tuần tự hóa là <X xsi:nil="true" />, trong đó có thể gần hơn với những gì bạn thực sự muốn ... trừ khi bạn chỉ muốn tạo XML của mình đẹp trai, sau đó nhận được lời đề nghị của Thomas.

7

Một mẫu XmlSerializer được hỗ trợ khác;

[DefaultValue({whatever})] 
public SomeType SomeProperty {get;set;} 

Lưu ý tuy nhiên đó parameterless bạn constructor phải gán giá trị này, hoặc kết quả không thể đoán trước sẽ xảy ra.

+0

ooo tôi không biết về điều này. –

+0

Giải pháp rất thanh lịch, phù hợp với tôi! –

Các vấn đề liên quan