2010-06-14 16 views
5

Aşağıdaki XML'i bir nesneye dönüştürmek/serileştirmek istiyorum.Xml'den C# ile birden çok veri türü içeren bir liste nasıl serileştirilir?

<Discounts> 
     <Discount Type="Voucher" Key="ABCD00001" Percent="2" /> 
     <Discount Type="Quantity"> 
     <Periods> 
      <Period From="Thu, 31 Dec 2009 23:00:00 GMT" Quantity="1" /> 
      <Period From="Thu, 31 Dec 2009 23:00:00 GMT" Quantity="2" /> 
     </Periods> 
     </Discount> 
    </Discounts> 

@ Tür özniteliğinin serileştirmek için hangi nesne türünün kullanılması gerektiğini tanımlaması mümkün mü? C# Örneğin

:

[XmlArray] 
[XmlArrayItem("Discount",typeof(Voucher)] 
[XmlArrayItem("Discount",typeof(Quantity)] 
public List<Discount> Discounts { get; set; } 

benim açıklama mantıklı umuyoruz. Herhangi bir yardım takdir edilecektir. Teşekkürler.

Güncelleme Andrew Anderson cevap sonrası:

<Discounts> 
     <Discount xsi:Type="Voucher" Key="ABCD00001" Percent="2" /> 
     <Discount xsi:Type="Quantity"> 
     <Periods> 
      <Period From="Thu, 31 Dec 2009 23:00:00 GMT" Quantity="1" /> 
      <Period From="Thu, 31 Dec 2009 23:00:00 GMT" Quantity="2" /> 
     </Periods> 
     </Discount> 
    </Discounts> 

benim sınıfları değişti şöyle görünecek şekilde:

[Serializable] 
    [XmlInclude(typeof(Voucher))] 
    [XmlInclude(typeof(Quantity))] 
    [XmlRoot("Discount")] 
    public class Discount 
    { ... } 

    public class Quantity : Discount { } 

    public class Voucher : Discount { } 

bu deserialize

İşte

güncellenen XML 'İndirimler' listesinde iki 'İndirim' nesnesi vardır. Bu noktada listenin bir 'Miktar' nesnesi ve 'Kupon' nesnesinin olması beklenir. Bunun nedeni, listemin yalnızca bir 'İndirim' nesnesine sahip olması olarak tanımlanabilir. 'İndirimlerim' liste nesnesinin kodu aşağıdadır.

[XmlArray] 
    [XmlArrayItem("Discount")] 
    public List<Discount> Discounts { get; set; } 

Şimdi, soru, iki farklı nesne türünü içerecek şekilde listeyi nasıl ayarlayabilirim? Eğer XML üzerinde kontrol varsa

+0

, xml görünümü üzerinde esnek, ya da sen ettik tam olarak olmak zorunda gönderildi? –

+0

Biçimden siz sorumlusunuz mu? Eğer öyleyse, neden XML'de "VoucherDiscount" ve "QuantityDiscount" ile "İndirim" yerine? – Joseph

+0

Geldiğinde ve çıktığında bir stil sayfasını kullanmanın en kolayı gibi görünebilir, ancak bir şeyi değiştirmekten kaçınmak istiyorum. – chafnan

cevap

5

Bunu işlemek için İndirim temel sınıf üzerinde XmlInclude özelliğini kullanabilirsiniz.

Örneğin

(önde denenmemiş kodu):

[Serializable] 
[XmlInclude(typeof(Voucher))] 
[XmlInclude(typeof(Quantity))] 
[XmlRoot("Discount")] 
public class Discount { } 

public class Quantity : Discount { } 
public class Voucher : Discount { } 

çıkan Xml aşağıdaki gibi görünecektir:

<Discounts> 
    <Discount xsi:type="Voucher" Key="ABCD00001" Percent="2" /> 
    <Discount xsi:type="Quantity"> 
    <Periods> 
     <Period From="Thu, 31 Dec 2009 23:00:00 GMT" Quantity="1" /> 
     <Period From="Thu, 31 Dec 2009 23:00:00 GMT" Quantity="2" /> 
    </Periods> 
    </Discount> 
</Discounts> 

GÜNCELLEME: Burada

sınıfların örnek kümesidir ve Bu biçimden serileştirme & serileştirme göstermek için bir konsol uygulaması.

İlk veri tanımlama:

[Serializable] 
public class Shopping 
{ 
    [XmlArray] 
    [XmlArrayItem("Discount")] 
    public List<Discount> Discounts { get; set; } 
} 

[Serializable] 
[XmlInclude(typeof(Voucher))] 
[XmlInclude(typeof(Quantity))] 
[XmlRoot("Discount")] 
public class Discount 
{ 
    public int Amount { get; set; } 
} 

public class Quantity : Discount 
{ 
    public int MyQuantity { get; set; } 
} 

public class Voucher : Discount 
{ 
    public string MyVoucherName { get; set; } 
} 

Ve test uygulaması: Ayrıca

public class Program 
{ 
    static void Main(string[] args) 
    { 
     XmlSerializer xs = new XmlSerializer(typeof(Shopping)); 

     var myShopping = new Shopping(); 
     myShopping.Discounts = new List<Discount>(); 
     myShopping.Discounts.Add(new Voucher() {MyVoucherName = "Foo", Amount = 6}); 
     myShopping.Discounts.Add(new Quantity() { MyQuantity = 100, Amount = 6 }); 

     StringBuilder xml = new StringBuilder(); 
     XmlWriter xmlWriter = XmlWriter.Create(xml); 

     xs.Serialize(xmlWriter, myShopping); 

     Console.WriteLine("Serialized:"); 
     Console.WriteLine(xml); 

     Console.WriteLine(); 
     Console.WriteLine("Deserialized:"); 

     TextReader tr = new StringReader(xml.ToString()); 
     var myNewShopping = (Shopping) xs.Deserialize(tr); 

     if (myNewShopping.Discounts != null) 
     { 
      foreach (var discount in myNewShopping.Discounts) 
      { 
       if (discount is Voucher) 
       { 
        var voucher = (Voucher) discount; 
        Console.WriteLine("Voucher - Amount={0}, Name={1}", voucher.Amount, voucher.MyVoucherName); 
       } 
       else if (discount is Quantity) 
       { 
        var quantity = (Quantity)discount; 
        Console.WriteLine("Quantity - Amount={0}, #={1}", quantity.Amount, quantity.MyQuantity); 
       } 
       else 
       { 
        Console.WriteLine("Discount - Amount={0}", discount.Amount); 
       } 
      } 
     } 
     else 
     { 
      Console.WriteLine("No Discounts found"); 
     } 

     Console.ReadKey(); 
    } 
+0

Örneğimde bir sınıfa sahibim. Gönderinizde İndirimler Listesi'ni dekore edersiniz - [XmlArray] 'dan başka hiçbir özelliğe ihtiyacınız olmamalıdır. –

+0

Bu işe yaradı. Şimdi soru şu ki, Listede bulunan typeof nesnesi, "Miktar" veya "Makbuz" gibi yüklenen nesnenin türü olmasını istediğim "İndirim" dir. Yüklenen nesnelerin listede doğru olması neyse? – chafnan

+0

Üzgünüm, ilk yorumumu sildim çünkü cevabınızı yanlış okudum ve XmlInclude'ı yanlış yere uygulıyorum. – chafnan

İlgili konular