6

我在反序列化对象列表时遇到问题。我只能将一个对象序列化为一个对象,但无法获取列表。我没有收到任何错误,它只是返回一个空列表。这是返回的 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;
    }
}
4

5 回答 5

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);
于 2013-08-21T20:48:50.070 回答
3

我知道这是一个古老的(呃)问题,但我今天为此苦苦挣扎,并找到了一个不需要封装的答案。

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

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

  1. 您必须将 Xml 中的 Root 元素命名为ArrayOfxxx其中 xxx 是您的类的名称(或在 XmlType 中指定的名称(参见 2.))
  2. 如果您希望您的 xml 元素具有与该类不同的名称,则应XmlType在该类上使用。

注意:如果您的类型名称(或类名称)以小写字母开头,则应将第一个字符转换为大写。

示例 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; }
}
于 2014-05-26T15:47:32.220 回答
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;
于 2013-08-21T21:09:32.260 回答
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的错误是将列表项创建为根

于 2018-02-21T09:40:15.953 回答
-1

将 [XMLArray] 用于集合属性。

于 2015-02-16T13:23:38.577 回答