Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
449 views
in Technique[技术] by (71.8m points)

c# - XmlRootAttribute placement when deserializing to List

I have the following 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>

This is the code:

public class Program
{
    static void Main(string[] args)
    {
        var fs = new FileStream(@"D:empSites.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; }
}

The exception I get is: <Sites xmlns=''> was not expected.. The reason for this error is usually, when I don't define an XmlRoot for the XmlSerializer. But as you can see, I did that by decorating the class Site with the XmlRootAttribute

To complete my confusion, the following trick works:

Replace

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

with

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

Am I missing something?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

If you have control over the XML, then simply change:

<Sites> 

To

<ArrayOfSite xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

If you don't have control over the XML, create your own collection and deserialize into that.

[XmlRoot("Sites")]
public class Sites : List<Site>
{

}

Be careful when using the following constructor:

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

As Microsoft points out here, if you don't cache the instance of the serializer associated with List<Site>, you will end up with leaky memory...

Dynamically Generated Assemblies

To increase performance, the XML serialization infrastructure dynamically generates assemblies to serialize and deserialize specified types. The infrastructure finds and reuses those assemblies. This behavior occurs only when using the following constructors:

XmlSerializer.XmlSerializer(Type)

XmlSerializer.XmlSerializer(Type, String)

If you use any of the other constructors, multiple versions of the same assembly are generated and never unloaded, which results in a memory leak and poor performance. The easiest solution is to use one of the previously mentioned two constructors. Otherwise, you must cache the assemblies in a Hashtable, as shown in the following example.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...