4

我有以下 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. 但正如你所看到的,我通过SiteXmlRootAttribute

为了完成我的困惑,以下技巧有效:

代替

var serializer = new XmlSerializer(typeof(List<Site>));

var serializer = new XmlSerializer(typeof(List<Site>), new XmlRootAttribute("Sites"));

我错过了什么吗?

4

2 回答 2

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"));

正如微软在此处指出的那样,如果您不缓存与关联的序列化程序的实例List<Site>,您最终会出现内存泄漏......

动态生成的程序集

为了提高性能,XML 序列化基础结构动态生成程序集以序列化和反序列化指定类型。基础结构查找并重用这些程序集。此行为仅在使用以下构造函数时发生:

XmlSerializer.XmlSerializer(类型)

XmlSerializer.XmlSerializer(类型,字符串)

如果您使用任何其他构造函数,则会生成同一程序集的多个版本并且永远不会卸载,这会导致内存泄漏和性能下降。最简单的解决方案是使用前面提到的两个构造函数之一。否则,您必须将程序集缓存在 Hashtable 中,如下例所示。

于 2013-03-21T10:42:36.453 回答
4

The XmlRoot attribute you added to Site is not used, because you aren't deserializing an object of type Site. You are deserializing an object of type List<Site> and that's where the serializer looks for the XmlRoot attribute.

Your workaround actually is the correct solution. However, if you are performing this deserialization often in your program, be sure to cache the XmlSerializer instance, because that specific constructor doesn't internally cache the dynamically generated assemblies - this contrasts with the constructor you normally use.

于 2013-03-21T10:16:15.877 回答