使用C#中带注释的部分对XML进行序列化和反序列化

时间:2018-12-11 05:17:58

标签: c# .net xml

我想知道如何将注释的部分保留在XML中(序列化之后)。 有什么办法吗?

这是我的问题, 我有很多节点的XML文件。我的.NET应用程序将加载XML文件并序列化为C#类。然后将更改类中的某些节点(通过BL)并反序列化并再次保存文件。 保存后,我在某些节点上保留的注释会消失。

有什么方法可以避免使用C#重置XML注释?

预先感谢

1 个答案:

答案 0 :(得分:1)

假设这样的xml

<?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>

我们可以使用以下代码进行操作:

    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;
                        }
                    }
                }
            }
        }
    }
}