Search code examples
c#xml-serializationixmlserializable

serialize and store object in another object that implements IXmlSerializable


I would like to XML serialize instances of my object Exception and store it in the XMLNode[] Nodes property of another object ExceptionReport.

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Xml.Serialization.XmlSchemaProviderAttribute("ExportSchema")]
[System.Xml.Serialization.XmlRootAttribute(IsNullable = false)]
public partial class ExceptionReport : object, System.Xml.Serialization.IXmlSerializable
{
    public System.Xml.XmlNode[] Nodes { get; set; }

    public void ReadXml(System.Xml.XmlReader reader)
    {
        this.Nodes = System.Runtime.Serialization.XmlSerializableServices.ReadNodes(reader);
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        System.Runtime.Serialization.XmlSerializableServices.WriteNodes(writer, this.Nodes);
    }
}
public class Exception
{
    public string ExceptionText;
    public string exceptionCode;
    public string locator;
}

How would i go about doing this so the result would be something like this:

<ExceptionReport xmlns="http://www.opengis.net/ows" >
  <Exception exceptionCode="1">my first instance</Exception>
  <Exception exceptionCode="2">my second instance</Exception>
</ExceptionReport>

So far i have the following but i need to know how to serialize these objects and store them in the ExceptionReport Nodes array.

ExceptionReport er = new ExceptionReport();

Exception exception_item1 = new Exception();
exception_item1.ExceptionText = "my first instance";
exception_item1.exceptionCode = "1";

Exception exception_item2 = new Exception();
exception_item2.ExceptionText = "my second instance";
exception_item2.exceptionCode = "2";

List<Exception> exceptions = new List<Exception>( exception_item1, exception_item2 );

Solution

  • [XmlRoot("ExceptionReport")]
        public partial class ExceptionReport
        {
            [XmlElement("Exception")]
            public List<Exception> Nodes { get; set; }
    
            public ExceptionReport()
            {
                Nodes = new List<Exception>();
            }
        }
        public class Exception
        {
            [XmlText]
            public string ExceptionText;
            [XmlAttribute("exceptionCode")]
            public int ExceptionCode;
            [XmlAttribute("locator")]
            public string Locator;
        }
    

    Then to serialize, I use the following extensions:

    public static bool XmlSerialize<T>(this T item, string fileName)
            {
                return item.XmlSerialize(fileName, true);
            }
            public static bool XmlSerialize<T>(this T item, string fileName, bool removeNamespaces)
            {
                object locker = new object();
    
                XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces();
                xmlns.Add(string.Empty, string.Empty);
    
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
    
                XmlWriterSettings settings = new XmlWriterSettings();
                settings.Indent = true;
                settings.OmitXmlDeclaration = true;
    
                lock (locker)
                {
                    using (XmlWriter writer = XmlWriter.Create(fileName, settings))
                    {
                        if (removeNamespaces)
                        {
                            xmlSerializer.Serialize(writer, item, xmlns);
                        }
                        else { xmlSerializer.Serialize(writer, item); }
    
                        writer.Close();
                    }
                }
    
                return true;
            }
            public static T XmlDeserialize<T>(this string s)
            {
                object locker = new object();
                StringReader stringReader = new StringReader(s);
                XmlTextReader reader = new XmlTextReader(stringReader);
                try
                {
                    XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
                    lock (locker)
                    {
                        T item = (T)xmlSerializer.Deserialize(reader);
                        reader.Close();
                        return item;
                    }
                }
                finally
                {
                    if (reader != null)
                    { reader.Close(); }
                }
            }
            public static T XmlDeserialize<T>(this FileInfo fileInfo)
            {
                string xml = string.Empty;
                using (FileStream fs = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read))
                {
                    using (StreamReader sr = new StreamReader(fs))
                    {
                        return sr.ReadToEnd().XmlDeserialize<T>();
                    }
                }
            }
    

    Use like this:

    ExceptionReport report = new ExceptionReport();
                report.Nodes.Add(new Exception { ExceptionText = "my first instance", ExceptionCode = 1, Locator = "loc1" });
                report.Nodes.Add(new Exception { ExceptionText = "my second instance", ExceptionCode = 2 });
                report.XmlSerialize("C:\\test.xml");
    

    I tested and it came out like you wanted. Hope it helps...

    PS - The extensions came from my library on codeproject: http://www.codeproject.com/KB/dotnet/MBGExtensionsLibrary.aspx