简体   繁体   中英

Serialize and De-serialize XML with commented sections in C#

I was wondering that how i can keep the commented part in XML (After serialization). Is there any way to do so?

Here is my problem, I have XML file with lots of nodes. My .NET application will load the XML file and serialize into C# class. Then will change some nodes (by BL) in the class and de-serialize and save the file again. After saving, the comments i kept on some nodes are disappeared.

Is there is any way to avoid resetting of XML comments using C# ?

Thanks in advance

Suppose an xml like this

<?xml version="1.0" encoding="utf-8"?>
<Test>
    <!--Foo Description!-->
    <Foo>FooText</Foo>
    <!--Bar Description!-->
    <Bar>BarText</Bar>
</Test>

var xml = GenericSerializator<Test>.LoadObjectFromFile("test.xml");

xml.Foo += "1";
xml.FooCommnet += "2";
xml.Bar += "3";
xml.BarCommnet += "4";

GenericSerializator<Test>.SaveObjectToFile(xml, "test2.xml");

<?xml version="1.0" encoding="utf-16"?>
<Test>
  <!--Foo Description!2-->
  <Foo>FooText1</Foo>
  <!--Bar Description!4-->
  <Bar>BarText3</Bar>
</Test>

we can do it using this code:

    internal static class GenericSerializator<T> where T : class
    {
        public static T LoadObjectFromFile(string fileName)
        {
            using (var file = new FileStream(fileName, FileMode.Open, FileAccess.Read))
            {
                var xmlSerializer = new XmlSerializer(typeof(T));
                return (T)xmlSerializer.Deserialize(file);
            }
        }

        public static void SaveObjectToFile(object value, string fileName)
        {
            var xmlSerializer = new XmlSerializer(typeof(T));
            using (var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write))
            {
                fileStream.Seek(0, SeekOrigin.End);
                using (var streamWriter = new StreamWriter(fileStream, Encoding.Unicode))
                {
                    xmlSerializer.Serialize(streamWriter, value);
                }
            }
        }
    }

    public class Test : XmlSerializableWithComments
    {
        [XmlIgnore, Description]
        public string FooCommnet { get; set; }

        public string Foo { get; set; }

        [XmlIgnore, Description]
        public string BarCommnet { get; set; }

        public string Bar { get; set; }
    }

    public class XmlSerializableWithComments : IXmlSerializable
    {
        private PropertyInfo[] Properties { get; set; }

        public XmlSerializableWithComments()
        {
            Properties = GetType().GetProperties();

        }
        public void WriteXml(XmlWriter writer)
        {
            foreach (var propertyInfo in Properties)
            {
                var value = propertyInfo.GetValue(this, null).ToString();
                if (propertyInfo.IsDefined(typeof(DescriptionAttribute), false))
                {
                    writer.WriteComment(value);
                }
                else
                {
                    writer.WriteElementString(propertyInfo.Name, value);
                }

            }
        }
        public XmlSchema GetSchema()
        {
            throw new NotImplementedException();
        }

        public void ReadXml(XmlReader reader)
        {
            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.EndElement)
                {
                    reader.Read();
                }

                string comment = null;
                if (reader.NodeType == XmlNodeType.Comment)
                {
                    comment = reader.Value;
                }

                reader.Read();

                if (reader.NodeType == XmlNodeType.Element)
                {
                    var propertyName = reader.LocalName;

                    PropertyInfo temp;
                    if ((temp = Properties.FirstOrDefault(i => i.Name == propertyName)) != null)
                    {
                        reader.Read();
                        temp.SetValue(this, reader.Value);
                        if (!string.IsNullOrEmpty(comment))
                        {
                            if ((temp = Properties.FirstOrDefault(i => i.Name == propertyName + "Commnet")) != null)
                            {
                                temp.SetValue(this, comment);
                            }
                            comment = null;
                        }
                    }
                }
            }
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM