2010-11-04 17 views
14

मैं निम्नलिखित सी # वर्गों:सशर्त एक्सएमएल क्रमबद्धता

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 में मौजूद नहीं होना चाहिए।

उत्तर

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 मिनट तक हराया;) –

+2

मैं इस बात पर अस्पष्ट नहीं था कि उपरोक्त समाधान तब तक काम करता है जब तक मैं निम्नलिखित पोस्ट नहीं पढ़ता: http: //kjellsj.blogspot .com/2006/02/conditional-xml-serialization_08.html – Dean

+1

+1 सबसे अच्छी चीज जिसे मैं कभी नहीं जानता था :) बस इस मणि के साथ विशेष रूप से चिपचिपा पिछड़ा-संगतता समस्या हल हो गई। –

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

क्या यह वास्तव में शून्य/खाली वस्तुओं को छोड़ने के सवाल का जवाब दे रहा है? –

+1

@Will, नहीं, यह नहीं है ... –

+0

वास्तव में मेरा कोड शून्य तत्वों के लिए काम करता है, लेकिन यह खाली तत्वों के लिए काम नहीं करता है (वे अभी भी जेनरेट एक्सएमएल में मौजूद होंगे)। –

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

सबसे तेज़ समाधान और कम संभव बॉयलरप्लेट कोड के साथ ... –

+0

यह उत्तर होना चाहिए। चाहिए चाहिए * काम करता है, लेकिन [DefaultValue ("")] बहुत सरल विधि –

संबंधित मुद्दे