Search code examples
c#.netxmlxml-serializationxmlserializer

How to write a comment to an XML file when using the XmlSerializer?


I have an object Foo which I serialize to an XML stream.

public class Foo {
  // The application version, NOT the file version!
  public string Version {get;set;}
  public string Name {get;set;}
}

Foo foo = new Foo { Version = "1.0", Name = "Bar" };
XmlSerializer xmlSerializer = new XmlSerializer(foo.GetType());

This works fast, easy and does everything currently required.

The problem I'm having is that I need to maintain a separate documentation file with some minor remarks. As in the above example, Name is obvious, but Version is the application version and not the data file version as one could expect in this case. And I have many more similar little things I want to clarify with a comment.

I know I can do this if I manually create my XML file using the WriteComment() function, but is there a possible attribute or alternative syntax I can implement so that I can keep using the serializer functionality?


Solution

  • Isn't possible using default infrastructure. You need to implement IXmlSerializable for your purposes.

    Very simple implementation:

    public class Foo : IXmlSerializable
    {
        [XmlComment(Value = "The application version, NOT the file version!")]
        public string Version { get; set; }
        public string Name { get; set; }
    
    
        public void WriteXml(XmlWriter writer)
        {
            var properties = GetType().GetProperties();
    
            foreach (var propertyInfo in properties)
            {
                if (propertyInfo.IsDefined(typeof(XmlCommentAttribute), false))
                {
                    writer.WriteComment(
                        propertyInfo.GetCustomAttributes(typeof(XmlCommentAttribute), false)
                            .Cast<XmlCommentAttribute>().Single().Value);
                }
    
                writer.WriteElementString(propertyInfo.Name, propertyInfo.GetValue(this, null).ToString());
            }
        }
        public XmlSchema GetSchema()
        {
            throw new NotImplementedException();
        }
    
        public void ReadXml(XmlReader reader)
        {
            throw new NotImplementedException();
        }
    }
    
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class XmlCommentAttribute : Attribute
    {
        public string Value { get; set; }
    }
    

    Output:

    <?xml version="1.0" encoding="utf-16"?>
    <Foo>
      <!--The application version, NOT the file version!-->
      <Version>1.2</Version>
      <Name>A</Name>
    </Foo>
    

    Another way, maybe preferable: serialize with default serializer, then perform post-processing, i.e. update XML, e.g. using XDocument or XmlDocument.