A detailed example of Xml serialization and deserialization of XmlSerializer objects

  • 2020-06-07 04:21:26
  • OfStack

For this essay, the.Net namespace is System.Xml.Serialization; The sample code in this article needs to reference this namespace.
Why serialize and deserialize?
The Net program executes while the objects reside in memory; Objects in memory should be passed to other systems for use. Or it may need to be saved during the shutdown so that the next time the program is launched again, it may need to be serialized and deserialized.
Scope: This article only covers xml serialization, which can be serialized in base 2 or any other format.
Take a look at the simplest Xml serialization code

class Program
{
    static void Main(string[] args)
    {
        int i = 10;
        // The statement Xml Serialized object instance serializer
        XmlSerializer serializer = new XmlSerializer(typeof(int));
        // Performs the serialization and outputs the serialization results to the console 
        serializer.Serialize(Console.Out, i);
        Console.Read();
    }
}

The above code serializes int i and outputs the serialized results to the console as follows

<?xml version="1.0" encoding="gb2312"?>
<int>10</int>

The above serialized xml can be deserialized as follows

static void Main(string[] args)
{
    using (StringReader rdr = new StringReader(@"<?xml version=""1.0"" encoding=""gb2312""?>
<int>10</int>"))
    {
        // Declare the serialized object instance serializer
        XmlSerializer serializer = new XmlSerializer(typeof(int));
        // Deserialize and assign the deserialized result value to the variable i
        int i = (int)serializer.Deserialize(rdr);
        // Output the deserialization result 
        Console.WriteLine("i = " + i);
        Console.Read();
    }
}

The above code illustrates the process of xml serialization and deserialization in the simplest way. The Net system library does a lot of work for us. Serialization and deserialization are very simple. However, in reality, business requirements are often complex, so it is impossible to simply serialize 1 int variable. In the display, we need to serialize the complex type in a controlled manner.
Xml serialization of custom objects:
The ES29en.Xml.Serialization namespace has a series of feature classes that control the serialization of complex types. For example, XmlElementAttribute, XmlAttributeAttribute, XmlArrayAttribute, XmlArrayItemAttribute, XmlRootAttribute, and so on.
Look at a small example. There is a custom class Cat and the Cat class has three attributes: Color, Saying and Speed.

namespace UseXmlSerialization
{
    class Program
    {
        static void Main(string[] args)
        {
            // The statement 1 A cat object 
            var c = new Cat { Color = "White", Speed = 10, Saying = "White or black,  so long as the cat can catch mice,  it is a good cat" };

            // Serialize this object 
            XmlSerializer serializer = new XmlSerializer(typeof(Cat));

            // Serialize the object to the console 
            serializer.Serialize(Console.Out, c);

            Console.Read();
        }
    }
    [XmlRoot("cat")]
    public class Cat
    {
        // define Color Property to cat Properties of nodes 
        [XmlAttribute("color")]
        public string Color { get; set; }

        // Require non-serialization Speed attribute 
        [XmlIgnore]
        public int Speed { get; set; }

        // Set up the Saying Property serialized as Xml Child elements 
        [XmlElement("saying")]
        public string Saying { get; set; }
    }
}

You can use XmlElement to specify that a property is serialized to a child node (by default, it is); Or use the XmlAttribute feature to serialize attributes to Xml nodes. You can also modify the XmlIgnore feature to require the serializer not to serialize the modifier properties.
Xml serialization of object array:
Xml serialization of arrays needs to use XmlArrayAttribute and XmlArrayItemAttribute; XmlArrayAttribute specifies the Xml node name of the array element, and XmlArrayItemAttribute specifies the Xml node name of the array element.
The following code example:

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

namespace UseXmlSerialization
{
    class Program
    {
        static void Main(string[] args)
        {
            // The statement 1 A cat object 
            var cWhite = new Cat { Color = "White", Speed = 10, Saying = "White or black,  so long as the cat can catch mice,  it is a good cat" };
            var cBlack = new Cat { Color = "Black", Speed = 10, Saying = "White or black,  so long as the cat can catch mice,  it is a good cat" };

            CatCollection cc = new CatCollection { Cats = new Cat[] { cWhite,cBlack} };

            // Serialize this object 
            XmlSerializer serializer = new XmlSerializer(typeof(CatCollection));

            // Serialize the object to the console 
            serializer.Serialize(Console.Out, cc);

            Console.Read();
        }
    }
    [XmlRoot("cats")]
    public class CatCollection
    {
        [XmlArray("items"),XmlArrayItem("item")]
        public Cat[] Cats { get; set; }
    }

    [XmlRoot("cat")]
    public class Cat
    {
        // define Color Property to cat Properties of nodes 
        [XmlAttribute("color")]
        public string Color { get; set; }

        // Require non-serialization Speed attribute 
        [XmlIgnore]
        public int Speed { get; set; }

        // Set up the Saying Property serialized as Xml Child elements 
        [XmlElement("saying")]
        public string Saying { get; set; }
    }
}

The above code will output:

<?xml version="1.0" encoding="gb2312"?>
<cats xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://ww
w.w3.org/2001/XMLSchema">
  <items>
    <item color="White">
      <saying>White or black,  so long as the cat can catch mice,  it is a good
cat</saying>
    </item>
    <item color="Black">
      <saying>White or black,  so long as the cat can catch mice,  it is a good
cat</saying>
    </item>
  </items>
</cats>

XmlSerializer memory leak problem:
A careful look at msdn shows that there is indeed a leak. msdn explains as follows:
Dynamically generated assemblies
To improve performance, the XML serialization infrastructure will dynamically generate assemblies to serialize and deserialize specified types. This infrastructure will find and reuse these assemblies. This behavior occurs only when the following constructors are used:
XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type, String)
If any other constructor is used, multiple versions of the same 1 assembly will be generated and never uninstalled, leading to memory leaks and performance degradation. The simplest solution is to use one of the two constructors mentioned earlier. Otherwise, the assembly must be cached in Hashtable, as shown in the following example.
In other words, when we use the XmlSerializer serialization, initializing the XmlSerializer object, it is better to use the following two constructors or we will cause a memory leak.
XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type, String)

Related articles: