Проблемы десериализации Список объектов

У меня возникли проблемы с десериализацией списка объектов. Я могу получить только один объект для сериализации в объект, но не могу получить список. Я не получаю ошибки, он просто возвращает пустой список. Это возвращается XML:

<locations>
 <location locationtype="building" locationtypeid="1">
 <id>1</id>
 <name>Building Name</name>
 <description>Description of Building</description>
 </location>
</locations>

Это класс, который у меня есть, и десериализуюсь в методе GetAll:

[Serializable()]
[XmlRoot("location")]
public class Building
{
 private string method;
 [XmlElement("id")]
 public int LocationID { get; set; }
 [XmlElement("name")]
 public string Name { get; set; }
 [XmlElement("description")]
 public string Description { get; set; }
 [XmlElement("mubuildingid")]
 public string MUBuildingID { get; set; }
 public List<building> GetAll()
 {
 var listBuildings = new List<building>();
 var building = new Building();
 var request = WebRequest.Create(method) as HttpWebRequest;
 var response = request.GetResponse() as HttpWebResponse;
 var streamReader = new StreamReader(response.GetResponseStream());
 TextReader reader = streamReader;
 var serializer = new XmlSerializer(typeof(List<building>), 
 new XmlRootAttribute() { ElementName = "locations" });
 listBuildings = (List<building>)serializer.Deserialize(reader);
 return listBuildings;
 }
}
</building></building></building></building>
5 ответов

Попробуйте следующее:

[XmlRoot("locations")]
public class BuildingList
{
 public BuildingList() {Items = new List<building>();}
 [XmlElement("location")]
 public List<building> Items {get;set;}
}
</building></building>

Затем десериализуйте весь объект BuildingList.

var xmlSerializer = new XmlSerializer(typeof(BuildingList));
var list = (BuildingList)xmlSerializer.Deserialize(xml);


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

Успение 1: У вас есть контроль над исходным Xml и его построением.

Успение 2: Вы пытаетесь сериализовать Xml непосредственно в объект List

  • Вы должны указать элемент Root в Xml как ArrayOfxxx, где xxx - это имя вашего класса (или имя, указанное в XmlType (см. 2.))
  • Если вы хотите, чтобы ваши xml Elements имели другое имя для класса, вы должны использовать XmlType в классе.

NB: Если ваше имя типа (или имя класса) начинается с строчной буквы, вы должны преобразовать первый символ в верхний регистр.

Пример 1 - Без XmlType

class Program
{
 static void Main(string[] args)
 {
 //String containing the xml array of items.
 string xml =
@"<arrayofitem>
 <item>
 <name>John Doe</name>
 </item>
 <item>
 <name>Martha Stewart</name>
 </item>
</arrayofitem>";
 List<item> items = null;
 using (var mem = new MemoryStream(Encoding.Default.GetBytes(xml)))
 using (var stream = new StreamReader(mem))
 {
 var ser = new XmlSerializer(typeof(List<item>)); //Deserialising to List<item>
 items = (List<item>)ser.Deserialize(stream);
 }
 if (items != null)
 {
 items.ForEach(I => Console.WriteLine(I.Name));
 }
 else
 Console.WriteLine("No Items Deserialised");
 }
}
public class Item
{
 public string Name { get; set; }
}
</item></item></item></item>

Пример 2 - С XmlType

class Program
{
 static void Main(string[] args)
 {
 //String containing the xml array of items.
 //Note the Array Name, and the Title case on stq.
 string xml =
@"<arrayofstq>
 <stq>
 <name>John Doe</name>
 </stq>
 <stq>
 <name>Martha Stewart</name>
 </stq>
</arrayofstq>";
 List<item> items = null;
 using (var mem = new MemoryStream(Encoding.Default.GetBytes(xml)))
 using (var stream = new StreamReader(mem))
 {
 var ser = new XmlSerializer(typeof(List<item>)); //Deserialising to List<item>
 items = (List<item>)ser.Deserialize(stream);
 }
 if (items != null)
 {
 items.ForEach(I => Console.WriteLine(I.Name));
 }
 else
 Console.WriteLine("No Items Deserialised");
 }
}
[XmlType("stq")]
public class Item
{
 public string Name { get; set; }
}
</item></item></item></item>


Не знаете, как Building соответствует местоположению, которое у вас есть в вашем xml, но для меня это имеет смысл, если они названы одинаково. Вместо использования списка используйте LocationList, и он становится:

[Serializable()]
[XmlRoot("locations")]
public class LocationCollection{
 [XmlElement("location")]
 public Location[] Locations {get;set;}
}
[Serializable()]
[XmlRoot("location")]
public class Location
{ 
 [XmlElement("id")]
 public int LocationID { get; set; }
 [XmlAttribute("locationtype")]
 public string LocationType {get;set;}
 [XmlElement("name")]
 public string Name { get; set; }
 [XmlElement("description")]
 public string Description { get; set; }
 [XmlElement("mubuildingid")]
 public string MUBuildingID { get; set; } 
}

Затем вы можете выполнить десериализацию следующим образом:

var request = WebRequest.Create(method) as HttpWebRequest;
var response = request.GetResponse() as HttpWebResponse;
var streamReader = new StreamReader(response.GetResponseStream());
TextReader reader = streamReader;
var serializer = new XmlSerializer(typeof(LocationCollection), 
 new XmlRootAttribute() { ElementName = "locations" });
var listBuildings = (LocationCollection)serializer.Deserialize(reader);
return listBuildings;


Я знаю, старый вопрос, но столкнулся с ним, столкнувшись с подобной проблемой. Основываясь на ответе @ricovox и в контексте вопроса OP, это модель, которую я бы использовал для сериализации его xml:

[Serializable, XmlRoot("locations")]
public class BuildingList
{
 [XmlArrayItem("location", typeof(Building))]
 public List<building> locations { get; set; }
}
[Serializable]
public class Building
{
 public int LocationID { get; set; }
 public string Name { get; set; }
 public string Description { get; set; }
 public string MUBuildingID { get; set; }
 public List<building> GetAll()
 {
 ...
 }
}
</building></building>

Ошибка OP заключалась в том, чтобы создать элемент списка в качестве корневого


Используйте [XMLArray] для свойств коллекции.

licensed under cc by-sa 3.0 with attribution.