Десериализация некоторого XML (через поток) в родительские / дочерние объекты - PullRequest
1 голос
/ 04 августа 2010

У меня есть довольно простая сборка DAL, которая состоит из SalesEnquiry класса, который содержит List<T> другого Vehicle класса.

Мы будем получать файлы XML по электронной почте, что яхочу использовать для заполнения экземпляров моего класса SalesEnquiry, поэтому я пытаюсь использовать десериализацию.

Я добавил XMLRoot / XMLElement / XMLIgnore атрибуты для обоих классов, как мне кажетсяявляется целесообразным.Однако, когда я пытаюсь десериализовать, родительский объект SalesEnquiry заполняется, но не дочерние объекты Vehicle.

Я понимаю, что десериализация List<T> может быть сложной, но я не уверен, почему, какизбегайте проблем, или даже если из-за этого я борюсь.

Во время отладки я успешно сериализировал объект Vehicle самостоятельно, поэтому я предполагаю, что движусь в правильном направлении,но когда я отменяю сериализацию SalesEnquiry XML (который содержит один или несколько дочерних транспортных средств), List<Vehicle> не заполняется.

Где я иду не так?

Обновление:

В тестовом проекте я сериализовал SalesEnquiry, содержащий два автомобиля, и сохранил в файл.Затем я загрузил файл, десериализовав его обратно в другой объект SalesEnquiry.Это сработало!

Так в чем же разница?Транспортные средства были записаны следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<enquiry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <enquiry_no>100001</enquiry_no>
  <vehicles>
    <Vehicle>
      <vehicle_type>Car</vehicle_type>
      <vehicle_make>Ford</vehicle_make>
      <vehicle_model>C-Max</vehicle_model>
...

Следует отметить, что у автомобиля есть начальный капитал, а у моего входящего XML нет.В моем классе Vehicle я дал классу атрибут [XmlRoot("vehicle")], который я бы сделал ссылкой, но, очевидно, это не так.Думаю, это имеет смысл, потому что хотя Vehicle - это сам по себе класс, это всего лишь элемент массива в List внутри моего SalesEnquiry.

В этом случае возникает вопрос - Как мнеаннотируйте класс Vehicle так, чтобы я мог сопоставить входящие элементы XML (<vehicle>) с элементами моего списка (Vehicle)? [XmlArrayItem] (или [XmlElement] в этом отношении) «недопустимы вэтот тип объявления '.

В этом примере я могу попросить людей, которые генерируют XML, использовать <Vehicle> вместо <vehicle>, но могут быть ситуации, когда у меня нет этой свободы, поэтомуЯ лучше изучу решение, чем применю обходной путь.


Заключение :

Добавляя [XmlArrayItem ("vehicle", typeof (Vehicle))]к существующему оформлению моего Списка, XML теперь может полностью десериализоваться.Уф!

1 Ответ

1 голос
/ 05 августа 2010

Вот рабочая пара классов с соответствующими украшениями:

(Примечание: XmlAnyElement и XmlAnyAttribute являются необязательными. Я имею привычку повышать гибкость сущности.)

[XmlType("enquiry")]
[XmlRoot("enquiry")]
public class Enquiry
{
    private List<Vehicle> vehicles = new List<Vehicle>();

    [XmlElement("enquiry_no")]
    public int EnquiryNumber { get; set; }

    [XmlArray("vehicles")]
    [XmlArrayItem("Vehicle", typeof(Vehicle))]
    public List<Vehicle> Vehicles
    {
        get { return this.vehicles; }
        set { this.vehicles = value ?? new List<Vehicle>(); }
    }

    [XmlAnyElement]
    public XmlElement[] AnyElements;
    [XmlAnyAttribute]
    public XmlAttribute[] AnyAttributes;
}

public class Vehicle
{
    [XmlElement("vehicle_type")]
    public string VehicleType { get; set; }
    [XmlElement("vehicle_make")]
    public string VehicleMake { get; set; }
    [XmlElement("vehicle_model")]
    public string VehicleModel { get; set; }
}
...