Conditional xml serialization
You should be able to use the ShouldSerialize*
pattern:
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); }}
Alternative :
- Switch your public fields to properties
- Define default values with the
DefaultValueAttribute
attribute - Define content property with the
ContentPropertyAttribute
attribute - Use XamlWriter/XamlReader
You end up with something like this:
[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; } }
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); }}
And if you want to remove the namespace from the root node:
var namespaces = new XmlSerializerNamespaces();namespaces.Add(string.Empty, string.Empty);serializer.Serialize(Console.Out, books, namespaces);
Also I would recommend you using properties instead of fields in your model classes for better encapsulation:
public class Books{ [XmlElement("Book")] public List<Book> BookList { get; set; }}