Skip to content

Instantly share code, notes, and snippets.

@heiswayi
Last active August 6, 2021 19:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save heiswayi/cb66748bc11efe360ad6c233fa8e603f to your computer and use it in GitHub Desktop.
Save heiswayi/cb66748bc11efe360ad6c233fa8e603f to your computer and use it in GitHub Desktop.
XML serialization & deserialization helper class | Blog: https://heiswayi.nrird.com/xml-serialization-deserialization
/*
MIT License
Copyright (c) 2016 Heiswayi Nrird
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace HeiswayiNrird.Utilities
{
public static class XmlHelper
{
/// <summary>
/// Serialize a serializable object to XML string.
/// </summary>
/// <typeparam name="T">Type of object</typeparam>
/// <param name="xmlObject">Type of object</param>
/// <param name="useNamespaces">Use of XML namespaces</param>
/// <returns>XML string</returns>
public static string SerializeToXmlString<T>(T xmlObject, bool useNamespaces = true)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
MemoryStream memoryStream = new MemoryStream();
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
xmlTextWriter.Formatting = Formatting.Indented;
if (useNamespaces)
{
XmlSerializerNamespaces xmlSerializerNamespaces = new XmlSerializerNamespaces();
xmlSerializerNamespaces.Add("", "");
xmlSerializer.Serialize(xmlTextWriter, xmlObject, xmlSerializerNamespaces);
}
else
{
xmlSerializer.Serialize(xmlTextWriter, xmlObject);
}
string output = Encoding.UTF8.GetString(memoryStream.ToArray());
string _byteOrderMarkUtf8 = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
if (output.StartsWith(_byteOrderMarkUtf8))
{
output = output.Remove(0, _byteOrderMarkUtf8.Length);
}
return output;
}
/// <summary>
/// Serialize a serializable object to XML string and create a XML file.
/// </summary>
/// <typeparam name="T">Type of object</typeparam>
/// <param name="xmlObject">Type of object</param>
/// <param name="filename">XML filename with .XML extension</param>
/// <param name="useNamespaces">Use of XML namespaces</param>
public static void SerializeToXmlFile<T>(T xmlObject, string filename, bool useNamespaces = true)
{
try
{
File.WriteAllText(filename, SerializeToXmlString<T>(xmlObject, useNamespaces));
}
catch
{
throw new Exception();
}
}
/// <summary>
/// Deserialize XML string to an object.
/// </summary>
/// <typeparam name="T">Type of object</typeparam>
/// <param name="xml">XML string</param>
/// <returns>XML-deserialized object</returns>
public static T DeserializeFromXmlString<T>(string xml)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
StringReader stringReader = new StringReader(xml);
return (T)xmlSerializer.Deserialize(stringReader);
}
/// <summary>
/// Deserialize XML string from XML file to an object.
/// </summary>
/// <typeparam name="T">Type of object</typeparam>
/// <param name="filename">XML filename with .XML extension</param>
/// <returns>XML-deserialized object</returns>
public static T DeserializeFromXmlFile<T>(string filename) where T : new()
{
if (!File.Exists(filename))
{
throw new FileNotFoundException();
}
return DeserializeFromXmlString<T>(File.ReadAllText(filename));
}
}
}
@haifenghuang
Copy link

In the DeserializeFromXmlString function, you don't need to use new(), below is why:

    public static T DeserializeFromXmlString<T>(string xml) where T : new()
    {
            T xmlObject = new T();                                   // HERE you created a NEW 'T' and assigned to variable xmlObject.
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
            StringReader stringReader = new StringReader(xml);
            xmlObject = (T)xmlSerializer.Deserialize(stringReader);  // HERE you reassigned xmlObject create at the first line
            return xmlObject;
    }

We just need to return the de-serialized object, so I think below code should be better:

    public static T DeserializeFromXmlString<T>(string xml)
    {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
            StringReader stringReader = new StringReader(xml);
            return (T)xmlSerializer.Deserialize(stringReader);
    }

@heiswayi
Copy link
Author

heiswayi commented Aug 6, 2020

Thanks for pointing out! I've updated the snippet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment