2010-11-04 22 views
14

Ben aşağıdaki C# sınıfların:Şartlı xml seri hale

public class Books 
{ 

public List<Book> BookList; 

} 

public class Book 
{ 

public string Title; 
public string Description; 
public string Author; 
public string Publisher; 

} 

nasıl aşağıdaki XML içine bu sınıf serileştirebilirsiniz?

<Books> 
    <Book Title="t1" Description="d1"/> 
    <Book Description="d2" Author="a2"/> 
    <Book Title="t3" Author="a3" Publisher="p3"/> 
</Books> 

XML'in yalnızca değerleri boş/boş olmayan özelliklere sahip olmasını istiyorum. Örneğin: İlk Kitap öğesinde, yazar boştur, bu nedenle serileştirilmiş XML'de bulunmamalıdır.

cevap

29

ShouldSerialize* modelini kullanabilmeniz gerekir:

public class Book 
{ 
    [XmlAttribute] public string Title {get;set;} 
    public bool ShouldSerializeTitle() { 
     return !string.IsNullOrEmpty(Title); 
    } 

    [XmlAttribute] public string Description {get;set;} 
    public bool ShouldSerializeDescription() { 
     return !string.IsNullOrEmpty(Description); 
    } 

    [XmlAttribute] public string Author {get;set;} 
    public bool ShouldSerializeAuthor() { 
     return !string.IsNullOrEmpty(Author); 
    } 

    [XmlAttribute] public string Publisher {get;set;} 
    public bool ShouldSerializePublisher() { 
     return !string.IsNullOrEmpty(Publisher); 
    } 
} 
+0

bana 1 dakikayı geçersiniz;) –

+2

Yukarıdaki çözümü okuyana kadar yukarıdaki çözümün nasıl çalıştığını açıklamamıştım: http: //kjellsj.blogspot com.tr/2006/02/conditional-xml-serialization_08.html – Dean

+1

+1 Hiç bilmediğim en havalı şey :) Sadece bu gemiyle özellikle yapışkan geriye dönük uyumluluk sorunu çözüldü. –

1
public class Books 
{ 
    [XmlElement("Book")] 
    public List<Book> BookList; 
} 

public class Book 
{ 
    [XmlAttribute] 
    public string Title; 
    [XmlAttribute] 
    public string Description; 
    [XmlAttribute] 
    public string Author; 
    [XmlAttribute] 
    public string Publisher; 
} 

class Program 
{ 
    static void Main() 
    { 
     var books = new Books 
     { 
      BookList = new List<Book>(new[] 
      { 
       new Book 
       { 
        Title = "t1", 
        Description = "d1" 
       }, 
       new Book 
       { 
        Author = "a2", 
        Description = "d2" 
       }, 
       new Book 
       { 
        Author = "a3", 
        Title = "t3", 
        Publisher = "p3" 
       }, 
      }) 
     }; 

     var serializer = new XmlSerializer(books.GetType()); 
     serializer.Serialize(Console.Out, books); 
    } 
} 

Ve kök düğümden ad kaldırmak isterseniz:

public class Books 
{ 
    [XmlElement("Book")] 
    public List<Book> BookList { get; set; } 
} 
:

var namespaces = new XmlSerializerNamespaces(); 
namespaces.Add(string.Empty, string.Empty); 
serializer.Serialize(Console.Out, books, namespaces); 

Ayrıca sana daha iyi encapsulation'ı properties yerine modeli sınıflarında fields kullanarak öneriyoruz

+5

Bu aslında boş/boş öğelerin atlanmasıyla ilgili soruyu yanıtlıyor mu? –

+1

@Will, hayır değil ... –

+0

Gerçekten de kodum boş öğeler için çalışıyor, ancak boş öğeler için çalışmıyor (oluşturulmuş XML'de hala mevcut olacaklar). –

6

Alternatif:

  • DefaultValueAttribute özniteliği
  • ContentPropertyAttribute özelliği olan içerik özelliğini tanımlayın ile varsayılan değerleri tanımlayın özelliklerine genel alanları geçin
  • Kullanım XamlWriter/XamlReader

Böyle bir şey ile sonuna kadar:

[ContentProperty("Books")] 
public class Library { 

    private readonly List<Book> m_books = new List<Book>(); 

    public List<Book> Books { get { return m_books; } } 

} 

public class Book 
{ 

    [DefaultValue(string.Empty)] 
    public string Title { get; set; } 

    [DefaultValue(string.Empty)] 
    public string Description { get; set; } 

    [DefaultValue(string.Empty)] 
    public string Author { get; set; } 

} 
+0

En hızlı çözüm ve daha az boilerplate kodu ile ... –

+0

Bu cevap olmalı. ShouldSerialize * çalışır, ancak [DefaultValue ("")] çok daha basit bir yöntemle –

İlgili konular