我有以下XML
<?xml version="1.0" encoding="UTF-16" standalone="no"?>
<Sites>
<Site>
<Code>TWTR</Code>
<Name>twitter.com</Name>
</Site>
<Site>
<Code>FB</Code>
<Name>facebook.com</Name>
</Site>
<Site>
<Code>SO</Code>
<Name>stackoverflow.com</Name>
</Site>
</Sites>
这是代码:
public class Program
{
static void Main(string[] args)
{
var fs = new FileStream(@"D:\temp\Sites.xml", FileMode.Open);
var serializer = new XmlSerializer(typeof(List<Site>));
var instance = (List<Site>)serializer.Deserialize(fs);
}
}
[XmlRoot("Sites")]
public class Site
{
public string Code { get; set; }
public string Name { get; set; }
}
我得到的例外是:<Sites xmlns=''> was not expected.
。当我没有为XmlSerializer
定义XmlRoot时,通常会出现此错误的原因。但正如您所看到的,我通过使用Site
XmlRootAttribute
来做到这一点
为了完成我的困惑,以下技巧有效:
替换
var serializer = new XmlSerializer(typeof(List<Site>));
与
var serializer = new XmlSerializer(typeof(List<Site>), new XmlRootAttribute("Sites"));
我错过了什么吗?
答案 0 :(得分:5)
如果您可以控制XML,则只需更改:
<Sites>
要
<ArrayOfSite xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
如果您无法控制XML,请创建自己的集合并反序列化。
[XmlRoot("Sites")]
public class Sites : List<Site>
{
}
使用以下构造函数时要小心:
var serializer = new XmlSerializer(typeof(List<Site>), new XmlRootAttribute("Sites"));
正如微软指出here,如果你没有缓存与List<Site>
相关联的序列化程序的实例,你最终会泄漏内存......
动态生成的程序集
提高性能,XML序列化基础架构 动态生成程序集以序列化和反序列化 指定的类型。基础结构查找并重用这些程序集。 仅当使用以下构造函数时才会出现此问题:
XmlSerializer.XmlSerializer(类型):
XmlSerializer.XmlSerializer(Type,String)
如果您使用任何其他构造函数,则使用多个版本 生成相同的装配并且从不卸载,这导致a 内存泄漏和性能不佳。最简单的解决方案是使用一个 前面提到的两个构造函数。否则,你必须 将程序集缓存在Hashtable中,如下所示 示例
答案 1 :(得分:3)
您未添加XmlRoot
添加到Site
的{{1}}属性,因为您没有反序列化Site
类型的对象。您正在反序列化List<Site>
类型的对象,这是序列化程序查找XmlRoot
属性的位置。
您的解决方法实际上是正确的解决方案。但是,如果您经常在程序中执行此反序列化,请确保缓存XmlSerializer
实例,因为该特定构造函数不会在内部缓存动态生成的程序集 - 这与您通常使用的构造函数形成对比。