2014-11-28 2 views
2

У меня есть XML от стороннего программного обеспечения, которое мне нужно десериализовать, но у меня есть спецификация XML.C# Deserialize XML в список ChildClasses

В какой-то момент у меня есть узел, содержащий кучу разных узлов разных типов. Мне нужно десериализовать этот узел (транспортные средства) в качестве списка. Каждый из дочерних узлов один подкласс класса Vehicle

public List<Vehicle> Vehicles = new List<Vehicles>(); 

определение класса выглядит следующим образом

public class Vehicle 
{ 
    public string Vehicletype { get; set; } 

    public virtual bool Drive() { return true; } 
} 

public class Car:Vehicle 
{ 
    public int NumberOfDoors { get; set; } 

    public override bool Drive() { return false; } 
} 

public class Boat:Vehicle 
{ 
    public int NumberOfSeats { get; set; } 
} 

Определение XML выглядит следующим образом

<vehicles> 
    <car NumberOfDoors="4" /> 
    <car NumberOfDoors="3" /> 
    <boat NumberOfSeats="1024" /> 
    <boat NumberOfSeats="20" /> 
    <car NumberOfDoors="5" /> 
</vehicles> 

На в какой-то момент мне нужно пройти через них и позволить им «Диск». У меня нет опыта с определениями XMLSchema. Теперь я использую VehicleType на фабрике и некоторые другие вещи. Это в основном становится беспорядком.

Мне нужно было бы предложить, чтобы Сериализатор сделал это вместо меня. Я сомневаюсь, что я первый, у кого есть эта проблема.

ответ

2

Во-первых, вы должны отметить NumberofSeats и NumberOfDoors с атрибутом XmlAttribute сказать XmlSerializer, что эти свойства должны выглядеть как атрибуты XML:

public class Car : Vehicle 
{ 
    [XmlAttribute] 
    public int NumberOfDoors { get; set; } 

    public override bool Drive() { return false; } 
} 

public class Boat : Vehicle 
{ 
    [XmlAttribute] 
    public int NumberOfSeats { get; set; } 
} 

Далее, если <vehicles> появляется как XML узел внутри некоторых содержащий root element, вы можете сделать свой public List<Vehicle> Vehicles как член внутри соответствующего класса контейнера и применить к нему атрибут XmlArray, чтобы указать, что список должен быть сериализован на двух уровнях, и XmlArrayItem атрибутов, чтобы сообщить XmlSerializer возможно транспортные средства, которые могут возникнуть в списке вместе с открывающим тегом, чтобы использовать для каждого из них:

public class VehiclesContainer // Your container class 
{ 
    [XmlArray("vehicles")] 
    [XmlArrayItem("vehicle", typeof(Vehicle))] 
    [XmlArrayItem("car", typeof(Car))] 
    [XmlArrayItem("boat", typeof(Boat))] 
    public List<Vehicle> Vehicles = new List<Vehicle>(); 
} 

С другой стороны, <vehicles> является корневым узлом документа XML и не содержащего узла, вы можете вводится класс корневого узла, содержащего список транспортных средств, а затем применить множественный XmlElement атрибутов, чтобы указать, что список должен быть сериализовать в одном уровне, а не два, наряду с начальным тегом использовать для каждого возможного типа транспортного средства:

[XmlRoot("vehicles")] 
public class VehicleList 
{ 
    [XmlElement("vehicle", typeof(Vehicle))] 
    [XmlElement("car", typeof(Car))] 
    [XmlElement("boat", typeof(Boat))] 
    public List<Vehicle> Vehicles = new List<Vehicle>(); 
} 

Сделав это, XmlSerializer автоматически десериализует ваши кланы иерархии.

Для получения дополнительной информации см. here.

+0

То, что мне было нужно – user853710