条件xml序列化

use*_*907 18 c# xml xml-serialization

我有以下C#类:

public class Books
{

public List<Book> BookList;

}

public class Book
{

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

}
Run Code Online (Sandbox Code Playgroud)

如何将此类序列化为以下XML?

<Books>
  <Book Title="t1" Description="d1"/>
  <Book Description="d2" Author="a2"/>
  <Book Title="t3" Author="a3" Publisher="p3"/>
</Books>
Run Code Online (Sandbox Code Playgroud)

我希望XML只包含那些值为null/empty的属性.例如:在第一个Book元素中,author是空白的,因此它不应出现在序列化XML中.

Mar*_*ell 39

你应该能够使用这种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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 在我阅读以下帖子之前,我不清楚上述解决方案是如何工作的:http://kjellsj.blogspot.com/2006/02/conditional-xml-serialization_08.html (3认同)
  • +1 我从来不知道的最酷的事情:) 刚刚用这个 gem 解决了一个特别棘手的向后兼容性问题。 (2认同)
  • 请注意,ShouldSerialize方法**应该在这里公开,不像其他情况,如PropertyGrid序列化控件,其中方法可以是私有的,但不能被忽略. (2认同)

Nic*_*uet 7

替代方案

  • 将您的公共字段切换到属性
  • 使用DefaultValueAttribute属性定义默认值
  • 使用ContentPropertyAttribute属性定义content 属性
  • 使用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; }

 }
Run Code Online (Sandbox Code Playgroud)