XmlSerializer List Item Element Name

后端 未结 8 2028
渐次进展
渐次进展 2020-12-05 09:36

I have a class PersonList

[XmlRoot(\"Persons\")]
PersonList : List

when I serialize this to XML, by default it wi

8条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-05 10:20

    I know it's an old question but I ran into the same problem and none of the solutions seems to adresse the OP's question. So here is my solution (comments are in french if you wonder) :

    #region Références
    using System.Collections.Generic;
    using System.Linq;
    using System.Xml;
    using System.Xml.Schema;
    using System.Xml.Serialization;
    #endregion
    
    namespace XmlSerializationTests
    {
        /// 
        /// Représente une liste qui peut être sérialisée en XML en tant que noeud racine.
        /// 
        /// Type des éléments de la liste.
        public class XmlSerializableList
            : List, IXmlSerializable
        {
            #region Variables
            private static readonly XmlSerializer _ItemSerializer = new XmlSerializer(typeof(T));
            private static readonly string _ItemName;
            private string _RootName;
            #endregion
    
            #region Méthodes
            /// 
            /// Initialisation statique
            /// 
            static XmlSerializableList()
            {
                _ItemName = (typeof(T).GetCustomAttributes(typeof(XmlRootAttribute), true).FirstOrDefault() as XmlRootAttribute)?.ElementName ?? typeof(T).Name;
            }
    
            /// 
            /// Obtient le nom racine.
            /// 
            protected virtual string RootName
            {
                get
                {
                    if (string.IsNullOrWhiteSpace(_RootName)) _RootName = (GetType().GetCustomAttributes(typeof(XmlRootAttribute), true).FirstOrDefault() as XmlRootAttribute)?.ElementName ?? GetType().Name;
                    return _RootName;
                }
            }
    
            /// 
            /// Obtient le nom des éléments.
            /// 
            protected virtual string ItemName
            {
                get { return _ItemName; }
            }
    
            /// 
            /// Cette méthode est réservée et ne doit pas être utilisée.Lorsque vous implémentez l'interface IXmlSerializable, vous devez retourner la valeur null (Nothing dans Visual Basic) à partir cette méthode et, si la spécification d'un schéma personnalisé est requise, appliquez à la place  à la classe.
            /// 
            ///   qui décrit la représentation XML de l'objet qui est généré par la méthode  et utilisé par la méthode .
            public XmlSchema GetSchema()
            {
                return null;
            }
    
            /// 
            /// Génère un objet à partir de sa représentation XML.
            /// 
            ///  source à partir de laquelle l'objet est désérialisé.
            public void ReadXml(XmlReader reader)
            {
                if (!reader.IsEmptyElement)
                {
                    reader.ReadStartElement();
                    while (reader.NodeType != XmlNodeType.EndElement)
                    {
                        T item = (T) _ItemSerializer.Deserialize(reader);
                        Add(item);
                    }
                    reader.ReadEndElement();
                }
                else reader.ReadStartElement();
            }
    
            /// 
            /// Convertit un objet en sa représentation XML.
            /// 
            ///  flux dans lequel l'objet est sérialisé.
            public void WriteXml(XmlWriter writer)
            {
                foreach (var i in this)
                {
                    XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                    ns.Add("", "");
                    _ItemSerializer.Serialize(writer, i, ns);
                }
            }
            #endregion
        }
    }
    

    And here a unit test class to demonstrate use and results :

    #region Références
    using System.IO;
    using System.Text;
    using System.Xml.Serialization;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    #endregion
    
    namespace XmlSerializationTests
    {
        [TestClass]
        public class XmlSerializableListTests
        {
            public class Person
            {
                public string FirstName { get; set; }
                public string LastName { get; set; }
                public int Birth { get; set; }
            }
    
            [XmlRoot("color")]
            public class ColorDefinition
            {
                [XmlElement("name")] public string Name { get; set; }
                [XmlElement("r")] public int Red { get; set; }
                [XmlElement("g")] public int Green { get; set; }
                [XmlElement("b")] public int Blue { get; set; }
            }
    
            public class Persons : XmlSerializableList
            {
            }
    
            [XmlRoot("colors")]
            public class ColorList : XmlSerializableList
            {
            }
    
            private T ReadXml(string text) where T : class
            {
                XmlSerializer serializer = new XmlSerializer(typeof (T));
                using (StringReader sr = new StringReader(text))
                {
                    return serializer.Deserialize(sr) as T;
                }
            }
    
            private string WriteXml(T data) where T : class
            {
                XmlSerializer serializer = new XmlSerializer(typeof(T));
                StringBuilder sb = new StringBuilder();
                using (StringWriter sw = new StringWriter(sb))
                {
                    serializer.Serialize(sw, data);
                    return sb.ToString();
                }
            }
    
            [TestMethod]
            public void ReadEmpty()
            {
                string xml = @"
    
    ";
                XmlSerializableList lst = ReadXml>(xml);
                Assert.AreEqual(0, lst.Count);
            }
    
            [TestMethod]
            public void ReadEmpty2()
            {
                string xml = @"
    ";
                XmlSerializableList lst = ReadXml>(xml);
                Assert.AreEqual(0, lst.Count);
            }
    
            [TestMethod]
            public void ReadSimpleItems()
            {
                string xml = @"
    
      0
      52
      79
    ";
                XmlSerializableList lst = ReadXml>(xml);
                Assert.AreEqual(3, lst.Count);
                Assert.AreEqual(0, lst[0]);
                Assert.AreEqual(52, lst[1]);
                Assert.AreEqual(79, lst[2]);
            }
    
            [TestMethod]
            public void ReadComplexItems()
            {
                string xml = @"
    
      
        Linus
        Torvalds
        1969
      
      
        Bill
        Gates
        1955
      
      
        Steve
        Jobs
        1955
      
    ";
                XmlSerializableList lst = ReadXml>(xml);
                Assert.AreEqual(3, lst.Count);
                Assert.AreEqual("Linus", lst[0].FirstName);
                Assert.AreEqual("Torvalds", lst[0].LastName);
                Assert.AreEqual(1969, lst[0].Birth);
                Assert.AreEqual("Bill", lst[1].FirstName);
                Assert.AreEqual("Gates", lst[1].LastName);
                Assert.AreEqual(1955, lst[1].Birth);
                Assert.AreEqual("Steve", lst[2].FirstName);
                Assert.AreEqual("Jobs", lst[2].LastName);
                Assert.AreEqual(1955, lst[2].Birth);
            }
    
            [TestMethod]
            public void ReadInheritedPersons()
            {
                string xml = @"
    
      
        Linus
        Torvalds
        1969
      
      
        Bill
        Gates
        1955
      
      
        Steve
        Jobs
        1955
      
    ";
                Persons lst = ReadXml(xml);
                Assert.AreEqual(3, lst.Count);
                Assert.AreEqual("Linus", lst[0].FirstName);
                Assert.AreEqual("Torvalds", lst[0].LastName);
                Assert.AreEqual(1969, lst[0].Birth);
                Assert.AreEqual("Bill", lst[1].FirstName);
                Assert.AreEqual("Gates", lst[1].LastName);
                Assert.AreEqual(1955, lst[1].Birth);
                Assert.AreEqual("Steve", lst[2].FirstName);
                Assert.AreEqual("Jobs", lst[2].LastName);
                Assert.AreEqual(1955, lst[2].Birth);
            }
    
            [TestMethod]
            public void ReadInheritedColors()
            {
                string xml = @"
    
      
        red
        255
        0
        0
      
      
        green
        0
        255
        0
      
      
        yellow
        255
        255
        0
      
    ";
                ColorList lst = ReadXml(xml);
                Assert.AreEqual(3, lst.Count);
                Assert.AreEqual("red", lst[0].Name);
                Assert.AreEqual(255, lst[0].Red);
                Assert.AreEqual(0, lst[0].Green);
                Assert.AreEqual(0, lst[0].Blue);
                Assert.AreEqual("green", lst[1].Name);
                Assert.AreEqual(0, lst[1].Red);
                Assert.AreEqual(255, lst[1].Green);
                Assert.AreEqual(0, lst[1].Blue);
                Assert.AreEqual("yellow", lst[2].Name);
                Assert.AreEqual(255, lst[2].Red);
                Assert.AreEqual(255, lst[2].Green);
                Assert.AreEqual(0, lst[2].Blue);
            }
    
            [TestMethod]
            public void WriteEmpty()
            {
                string xml = @"
    ";
                XmlSerializableList lst = new XmlSerializableList();
                string result = WriteXml(lst);
                Assert.AreEqual(xml, result);
            }
    
            [TestMethod]
            public void WriteSimpleItems()
            {
                string xml = @"
    
      0
      52
      79
    ";
                XmlSerializableList lst = new XmlSerializableList() {0, 52, 79};
                string result = WriteXml(lst);
                Assert.AreEqual(xml, result);
            }
    
            [TestMethod]
            public void WriteComplexItems()
            {
                string xml = @"
    
      
        Linus
        Torvalds
        1969
      
      
        Bill
        Gates
        1955
      
      
        Steve
        Jobs
        1955
      
    ";
                XmlSerializableList persons = new XmlSerializableList
                {
                    new Person {FirstName = "Linus", LastName = "Torvalds", Birth = 1969},
                    new Person {FirstName = "Bill", LastName = "Gates", Birth = 1955},
                    new Person {FirstName = "Steve", LastName = "Jobs", Birth = 1955}
                };
                string result = WriteXml(persons);
                Assert.AreEqual(xml, result);
            }
    
            [TestMethod]
            public void WriteInheritedPersons()
            {
                string xml = @"
    
      
        Linus
        Torvalds
        1969
      
      
        Bill
        Gates
        1955
      
      
        Steve
        Jobs
        1955
      
    ";
                Persons lst = new Persons
                {
                    new Person {FirstName = "Linus", LastName = "Torvalds", Birth = 1969},
                    new Person {FirstName = "Bill", LastName = "Gates", Birth = 1955},
                    new Person {FirstName = "Steve", LastName = "Jobs", Birth = 1955}
                };
                string result = WriteXml(lst);
                Assert.AreEqual(xml, result);
            }
    
            [TestMethod]
            public void WriteInheritedColors()
            {
                string xml = @"
    
      
        red
        255
        0
        0
      
      
        green
        0
        255
        0
      
      
        yellow
        255
        255
        0
      
    ";
                ColorList lst = new ColorList
                {
                    new ColorDefinition { Name = "red", Red = 255, Green = 0, Blue = 0 },
                    new ColorDefinition { Name = "green", Red = 0, Green = 255, Blue = 0 },
                    new ColorDefinition { Name = "yellow", Red = 255, Green = 255, Blue = 0 }
                };
                string result = WriteXml(lst);
                Assert.AreEqual(xml, result);
            }
        }
    }
    

提交回复
热议问题