2010-11-04 20 views
14

我有以下的C#類:條件XML序列

public class Books 
{ 

public List<Book> BookList; 

} 

public class Book 
{ 

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

} 

我如何序列化這個類爲以下XML?

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

我希望XML只有那些其值不爲空/空的屬性。 例如:在第一個Book元素中,作者是空白的,所以它不應該出現在序列化的XML中。

回答

29

您應該可以使用ShouldSerialize*模式:

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

你打我1分鐘;) – 2010-11-04 09:22:25

+2

我不清楚上述解決方案如何工作,直到我看了下面的帖子:http://kjellsj.blogspot .com/2006/02/conditional-xml-serialization_08.html – Dean 2011-11-02 15:59:12

+1

+1我從來不知道的最酷的東西:)剛剛解決了這個寶石特別粘滯的向後兼容性問題。 – 2013-09-12 09:17:56

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

如果你想從根節點刪除的命名空間:

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

另外我想你使用的properties代替fields在你的模型類更好的封裝推薦

+5

這實際上是回答有關跳過空/空項目的問題嗎? – 2010-11-04 09:00:37

+1

@是的,不,它不是... – 2010-11-04 09:18:23

+0

事實上,我的代碼適用於空元素,但它不適用於空白元素(它們仍將存在於生成的XML中)。 – 2010-11-04 10:41:41

6

替代品:

  • 切換你的公共領域性質
  • 定義默認值與DefaultValueAttribute屬性
  • 定義內容屬性與ContentPropertyAttribute屬性
  • 使用的XamlWriter/XamlReader

你最終是這樣的:

[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

最快的解決方案和較少可能的樣板代碼... – 2014-04-03 17:26:10

+0

這應該是答案。 ShouldSerialize *的作品,但[DefaultValue(「」)]是簡單得多的方法 – 2014-07-14 04:56:35