How to Write a Comment to an Xml File When Using the Xmlserializer

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

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.

How to insert XML comments in XML Serialization?

Just put an XmlWriter as an intermediate level between the MemoryStream and the XmlSerializer:

static public MemoryStream SerializeToXML(MyWrapper list)
{
XmlSerializer serializer = new XmlSerializer(typeof(MyWrapper));
MemoryStream stream = new MemoryStream();
XmlWriter writer = XmlWriter.Create(stream);
writer.WriteStartDocument();
writer.WriteComment("Product XY Version 1.0.0.0");
serializer.Serialize(writer, course);
writer.WriteEndDocument();
writer.Flush();
return stream;
}

Your can add any XML before and after the serialized object graph (as long as the result is valid XML).

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

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

Add XML Comment during serialize/deserialize with VB.NET

No, there isn't. If you want to serialize the contents then you will have to use custom serialization (I assume you are referring to implementing the IXmlSerializable interface) and store the comments in the instance of the class and reserialize them when serializing back to XML.

The runtime can't possibly know that the comment is supposed to be serialized and store it for you, so you have to do it yourself.

C# XML Insert comment into XML after xml tag

Serialize it to XML, load that XML as an XDocument (or whatever API you want), insert the comment, save it out again. Simple, and should work with whatever API you want to use. You can do it all in memory using a MemoryStream as the temporary storage.

There may be a way of serializing directly into a new XDocument/XmlDocument, but I'm not aware of it.



Related Topics



Leave a reply



Submit