2013-05-15 31 views
9

Şu anda üzerinde hiçbir denetimim bulunmayan aşağıdaki XML yapısına (kısaltılmış olarak düzenlenmiş) sahibim. Bu Araç sınıfının tek örneği haline XML serisini edebilmek istiyorumİç içe XML nesnesini C# sınıfına deserialize edin. #

[XmlRoot("GetVehicles"), XmlType("Vehicle")] 
public class Vehicle 
{ 
    public string Colour { get; set; } 
    public string NumOfDoors { get; set; } 
    public string BodyStyle { get; set; } 
} 

:

<GetVehicles> 
    <ApplicationArea> 
     <Sender> 
      <Blah></Blah> 
     </Sender> 
    </ApplicationArea> 
    <DataArea> 
     <Error> 
      <Blah></Blah> 
     </Error> 
     <Vehicles> 
      <Vehicle> 
       <Colour>Blue</Colour> 
       <NumOfDoors>3</NumOfDoors> 
       <BodyStyle>Hatchback</BodyStyle> 
      <Vehicle> 
     </Vehicles> 
    </DataArea> 
</GetVehicles> 

Ben şu Class var. Zamanın% 99'u, XML'in yalnızca bir 'Araç' öğesi döndürmesi gerekir. Henüz 'Taşıt' unsuru içinde birden fazla 'Araç' öğesi içeriyorsa henüz ilgilenmiyorum.

Maalesef XML verileri şu anda sınıf özelliklerime eşlenmiyor; Deserialize yöntemimi çağırdıktan sonra boş bırakılıyorlar. Ben veri ayıklama sadece ilgincim

private static T Deserialize<T>(string data) where T : class, new() 
{ 
    if (string.IsNullOrEmpty(data)) 
     return null; 

    var ser = new XmlSerializer(typeof(T)); 

    using (var sr = new StringReader(data)) 
    { 
     return (T)ser.Deserialize(sr); 
    } 
} 

Böyle vb 'ApplicationArea', 'Hata' gibi daha üst elemanları umurumda değil: Bütünlüğü için

, burada benim Deserialize yöntemidir 'Araç' öğesi içinde. Bu verileri XML'den yalnızca serileştirmek için nasıl alabilirim?

cevap

6

Sorununuzun tam bağlamından haberdar değilim, bu nedenle bu çözüm etki alanınıza sığmayabilir.

[XmlRoot("Vehicle")] //<-- optional 
public class Vehicle 
{ 
    public string Colour { get; set; } 
    public string NumOfDoors { get; set; } 
    public string BodyStyle { get; set; } 
} 

ve XML LINQ kullanarak Deserialize yöntem haline özgü düğüm geçmesi: Ama bir çözüm olarak modelinizi tanımlamaktır

var vehicle = XDocument.Parse(xml) 
         .Descendants("Vehicle") 
         .First(); 

Vehicle v = Deserialize<Vehicle>(vehicle.ToString()); 


//display contents of v 
Console.WriteLine(v.BodyStyle); //prints Hatchback 
Console.WriteLine(v.Colour);  //prints Blue 
Console.WriteLine(v.NumOfDoors); //prints 3 
+0

Harika çalışıyor. Çok teşekkürler. – marcusstarnes

6

Yapı Ilya cevabı üzerine: Bu biraz optimize edilebilir

Zaten yüklü bir düğüm olduğundan, xml'yi bir dizgiye (vehicle.ToString() kullanarak) göndermeye gerek yoktur, sadece seri hale getiricinin onu yeniden ayrıştırması gerekir (StringReader kullanarak).

private static T Deserialize<T>(XmlNode data) where T : class, new() 
{ 
    if (data == null) 
     return null; 

    var ser = new XmlSerializer(typeof(T)); 
    using (var xmlNodeReader = new XmlNodeReader(data)) 
    { 
     return (T)ser.Deserialize(xmlNodeReader); 
    } 
} 

Sonra kullanabilirsiniz::

var vehicle = XDocument.Parse(xml) 
         .Descendants("Vehicle") 
         .First(); 

Vehicle v = Deserialize<Vehicle>(vehicle); 
verileri XmlNode ise

private static T Deserialize<T>(XNode data) where T : class, new() 
{ 
    if (data == null) 
     return null; 

    var ser = new XmlSerializer(typeof(T)); 
    return (T)ser.Deserialize(data.CreateReader()); 
} 

Veya, bir XmlNodeReader kullanın:

Bunun yerine, doğrudan XNode.CreateReader kullanarak bir okuyucu oluşturulmuş olabilir

+0

Harika not, teşekkürler. –

+0

Evet, benim için iyi çalıştı ve XmlNode kullanıyordu. Ancak, kod hemen işe yaramadı. Aşağıdaki kodu kullanarak biraz değiştirmem gerekiyor: xmlNodeReader.ReadStartElement(); dönüş (T) ser.Deserialize (xmlNodeReader.ReadSubtree()); –

İlgili konular