Wednesday, May 21, 2008

Serialize and deserialize object to/from XmlNode

I've tried to serialize an object to XmlNode during big refactoring. This was pretty tricky, as far as there no standard way to perform such serialization in .NET Framework. After short search on Internet I've found the idea and have implemented it into corresponding methods:

        public static XmlNode SerializeObjectToXmlNode(Object obj)
{
if (obj == null)
throw new ArgumentNullException("Argument cannot be null");

XmlNode resultNode = null;
XmlSerializer xmlSerializer = new XmlSerializer(obj.GetType());
using (MemoryStream memoryStream = new MemoryStream())
{
try
{
xmlSerializer.Serialize(memoryStream, obj);
}
catch (InvalidOperationException)
{
return null;
}
memoryStream.Position = 0;
XmlDocument doc = new XmlDocument();
doc.Load(memoryStream);
resultNode = doc.DocumentElement;
}
return resultNode;
}
public static Object DeSerializeXmlNodeToObject(XmlNode node, Type objectType)
{
if (node == null)
throw new ArgumentNullException("Argument cannot be null");
XmlSerializer xmlSerializer = new XmlSerializer(objectType);
using (MemoryStream memoryStream = new MemoryStream())
{
XmlDocument doc = new XmlDocument();
doc.AppendChild(doc.ImportNode(node, true));
doc.Save(memoryStream);
memoryStream.Position = 0;
XmlReader reader = XmlReader.Create(memoryStream);
try
{
return xmlSerializer.Deserialize(reader);
}
catch
{
return objectType.IsByRef ? null : Activator.CreateInstance(objectType);
}
}
}

5 comments:

Oleg said...

It is better to use XmlNodeReader instead of saving XmlDocument to the stream.

Code snippet:

XmlDocument doc = new XmlDocument();

...

XmlSerializer serializer = new XmlSerializer(typeof(T));
XmlNodeReader reader = new XmlNodeReader(doc);
return (T)serializer.Deserialize(reader);

Bashir Magomedov said...

Hmm. Nice solution, I'll try it ;) Thanks.

mi.p said...

Bashir, thanks for posting this! Serailizing and deserializing to / from XMlNodes/objects is REALLY non-trivial. Your post helped me tremendously

Jean said...

XmlSerializer serializer = new XmlSerializer(value.GetType());
XmlDocument doc = new XmlDocument();
XPathNavigator nav = doc.CreateNavigator();
using (XmlWriter writer = nav.AppendChild())
{
writer.WriteStartDocument();
serializer.Serialize(writer, value);
writer.WriteEndDocument();
writer.Flush();
}
return doc.FirstChild;

Ananthu said...

Thanks for posting.It helped me a lot.