将XML反序列化为对象(需要返回对象列表)

时间:2012-06-28 16:56:43

标签: c# xml

开始使用XML和C#进行练习,并且出现“XML文档中存在错误(3,2)”的错误消息。看完文件后,我看不出有什么问题(请注意,我可能因为我是菜鸟而错过了一些东西)。我正在使用C#的控制台应用程序。我正在尝试返回一个冒险家列表,只是一个旁注,GEAR元素是可选的。以下是我到目前为止的情况:

XML文件 - 测试1

<?xml version="1.0" encoding="utf-8"?>
<Catalog>
    <Adventurer>
        <ID>001</ID>
        <Name>John Smith</Name>
        <Address>123 Fake Street</Address>
        <Phone>123-456-7890</Phone>
        <Gear>
            <Attack>
                <Item>
                    <IName>Sword</IName>
                    <IPrice>15.00</IPrice>
                </Item> 
                <Item>
                    <IName>Wand</IName>
                    <IPrice>20.00</IPrice>
                </Item>         
            </Attack>
            <Defense>
                <Item>
                    <IName>Shield</IName>
                    <IPrice>5.00</IPrice>
                </Item>
        </Defense>  
        </Gear>
    </Adventurer>
    <Adventurer>
        <ID>002</ID>
        <Name>Guy noone likes</Name>
        <Address>Some Big House</Address>
        <Phone>666-666-6666</Phone>
        <Gear></Gear>
    </Adventurer>
</Catalog>

C#Classes

public class Catalog
{
    List<Adventurer> Adventurers { get; set; }
}

public class Adventurer
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string Phone { get; set; }
    public Gear Gear { get; set; }
}

public class Gear
{
    public List<Item> Attack { get; set; }
    public List<Item> Defense { get; set; }
}

public class Item
{
    public string IName { get; set; }
    public decimal IPrice { get; set; }
}

序列化功能 - 第5行出现问题

Catalog obj = null;
string path = @"C:\Users\Blah\Desktop\test1.xml";
XmlSerializer serializer = new XmlSerializer(typeof(Catalog));
StreamReader reader = new StreamReader(path);
obj = (Catalog)serializer.Deserialize(reader);
reader.Close();

Console.ReadLine();

4 个答案:

答案 0 :(得分:3)

问题是目录中的冒险者列表:

<?xml version="1.0" encoding="utf-8"?>
<Catalog>
    <Adventurers> <!-- you're missing this -->
        <Adventurer>
        </Adventurer>
        ...
        <Adventurer>
        </Adventurer>
    </Adventurers> <!-- and missing this -->
</Catalog>

您没有Adventurers集合的包装元素。

编辑:顺便说一句,我找到了构建XML结构的最简单方法,并确保它是兼容的是在C#中创建对象,然后运行内置的XmlSerializer并使用它XML输出作为我创建的任何XML的基础,而不是手工形成。

答案 1 :(得分:2)

首先,“冒险者”属性不公开,无法访问,我认为查找错误的最佳方法是序列化您的对象,然后将结果与您的xml文件进行比较。

答案 2 :(得分:1)

您的XML与您的对象并不完全对齐......即这两个......

public string City { get; set; }

<Address>123 Fake Street</Address>

将城市更改为地址,反之亦然,它应该解决问题。

编辑:让这个在测试项目中工作,结合我们所有的答案......

<Adventurers>之后添加<Catalog>代码(</Adventurers>之前</Catalog>)并更改

List<Adventurer> Adventurers { get; set; }

public List<Adventurer> Adventurers { get; set; }

它适用于我。

答案 3 :(得分:1)

我能够通过几个小的更改(即Adventurer上的公共限定符)让你的xml反序列化。

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml.Serialization;

namespace TempSandbox
{
    [XmlRoot]
    public class Catalog
    {
        [XmlElement("Adventurer")]
        public List<Adventurer> Adventurers;

        private readonly static Type[] myTypes = new Type[] { typeof(Adventurer), typeof(Gear), typeof(Item) };
        private readonly static XmlSerializer mySerializer = new XmlSerializer(typeof(Catalog), myTypes);

        public static Catalog Deserialize(string xml)
        {
            return (Catalog)Utils.Deserialize(mySerializer, xml, Encoding.UTF8);
        }
    }

    [XmlRoot]
    public class Adventurer
    {
        public int ID;

        public string Name;

        public string Address;

        public string Phone;

        [XmlElement(IsNullable = true)]
        public Gear Gear;
    }

    [XmlRoot]
    public class Gear
    {
        public List<Item> Attack;

        public List<Item> Defense;
    }

    [XmlRoot]
    public class Item
    {
        public string IName;

        public decimal IPrice;
    }
}

我正在使用[XmlElement(“Adventurer”)]因为xml元素名称与类属性名称不完全匹配。

注意:我正在使用我手边已有的通用反序列化工具。