C# 将XML反序列化为对象(需要返回对象列表)
开始练习XML和C#,我收到一条错误消息“XML文档(3,2)中有一个错误”。在看了文件之后,我看不出有什么问题(请注意,我可能因为我是个疯子而错过了一些东西)。我现在正在使用C#的控制台应用程序。我试图返回一个冒险家列表和一个旁注,齿轮元素是可选的。以下是我到目前为止的情况: XML文件-Test1C# 将XML反序列化为对象(需要返回对象列表),c#,xml,C#,Xml,开始练习XML和C#,我收到一条错误消息“XML文档(3,2)中有一个错误”。在看了文件之后,我看不出有什么问题(请注意,我可能因为我是个疯子而错过了一些东西)。我现在正在使用C#的控制台应用程序。我试图返回一个冒险家列表和一个旁注,齿轮元素是可选的。以下是我到目前为止的情况: XML文件-Test1 <?xml version="1.0" encoding="utf-8"?> <Catalog> <Adventurer> <ID
<?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>
您的XML与您的对象不完全一致。。。也就是这两个
public string City { get; set; }
及
123假街
将城市更改为地址,或将城市更改为地址,这样可以解决问题
编辑:在一个测试项目中得到了这个结果,结合了我们所有的答案
在
之后添加
标签(在
之前添加
标签)并更改
List<Adventurer> Adventurers { get; set; }
List冒险家{get;set;}
到
publicslist冒险家{get;set;}
这对我来说很有效。问题是目录中的冒险家列表:
<?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的基础,而不是手动形成它。首先,“Adventurers”属性不是公共的,它是不可访问的,我认为找到错误的最佳方法是序列化对象,然后将结果与xml文件进行比较。我通过几个小改动(即Adventurer上的公共限定符)就可以让xml进行反序列化
使用系统;
使用System.Collections.Generic;
使用系统文本;
使用System.IO;
使用System.Xml.Serialization;
名称空间临时沙盒
{
[XmlRoot]
公共类目录
{
[XmlElement(“冒险家”)]
公开冒险家名单;
私有只读静态类型[]myTypes=新类型[]{typeof(冒险家)、typeof(装备)、typeof(物品)};
私有只读静态XmlSerializer mySerializer=新XmlSerializer(typeof(Catalog),myTypes);
公共静态目录反序列化(字符串xml)
{
return(Catalog)Utils.Deserialize(mySerializer、xml、Encoding.UTF8);
}
}
[XmlRoot]
公营冒险者
{
公共int ID;
公共字符串名称;
公共字符串地址;
公用串电话;
[XmlElement(IsNullable=true)]
公共齿轮;
}
[XmlRoot]
公共级装备
{
公开列表攻击;
公开辩护;
}
[XmlRoot]
公共类项目
{
公共字符串在南部;
公共价格;
}
}
我之所以使用[XmlElement(“Adventurer”)],是因为xml元素名称与类属性名称不完全匹配
注意:我正在使用手头已有的通用反序列化实用程序。谢谢您的更正。出于某种原因,我仍然会遇到相同的错误:/XmlSerializer只会忽略对象中不存在的任何元素,并且由于XML中未定义
City
,因此它将为其分配默认的null
值。请参见“”,其中一致意见是“不,他们不应该”。感谢您的提示。我能让它工作。所以我猜我必须在C#中创建一个“冒险家”,然后将其序列化为XML,对吗?@J-Y:我将使用C#代码中的示例数据创建一个典型的目录
,然后将其序列化为XML,以便在创建自己的XML内容时用作模板。
<Address>123 Fake Street</Address>
List<Adventurer> Adventurers { get; set; }
public List<Adventurer> Adventurers { get; set; }
<?xml version="1.0" encoding="utf-8"?>
<Catalog>
<Adventurers> <!-- you're missing this -->
<Adventurer>
</Adventurer>
...
<Adventurer>
</Adventurer>
</Adventurers> <!-- and missing this -->
</Catalog>
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;
}
}