反序列化对象列表的问题

时间:2013-08-21 20:35:28

标签: c# xml serialization

我无法反序列化对象列表。我只能获得一个对象序列化到一个对象但无法获取列表。我没有得到错误它只返回一个空列表。这是返回的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;
    }
}

5 个答案:

答案 0 :(得分:6)

试试这个:

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

然后反序列化整个BuildingList对象。

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

答案 1 :(得分:3)

我知道这是一个古老的(呃)问题,但今天我在努力解决这个问题,并找到了一个不需要封装的答案。

假设1:您可以控制源Xml及其构造方式。

假设2:您正在尝试将Xml直接序列化为List<T>对象

  1. 您必须将Xml中的Root元素命名为ArrayOfxxx,其中xxx是您的类的名称(或XmlType中指定的名称(请参阅2.))
  2. 如果您希望您的xml元素具有与该类不同的名称,则应在该类上使用XmlType
  3. 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; }
    }
    

    示例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; }
    }
    

答案 2 :(得分:2)

不确定Building是如何与xml中的位置对应的,但对我来说,如果它们被命名为等效则更有意义。而不是使用List使用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;

答案 3 :(得分:0)

我知道,这是一个古老的问题,但遇到类似的问题却遇到了它。 基于@ 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()
    {
        ...
    }
}

OP的错误是将列表项创建为根

答案 4 :(得分:-1)

将[XMLArray]用于集合属性。