Question32805732 - XmlNodeExtensions

CSharp · Console

/Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.Xml;
using System.IO;
using System.Diagnostics;


    public static class XmlNodeExtensions
    {
        public static XmlDocument AsXmlDocument<T>(this T o, XmlSerializerNamespaces ns = null, XmlSerializer serializer = null)
        {
            XmlDocument doc = new XmlDocument();
            using (XmlWriter writer = doc.CreateNavigator().AppendChild())
                new XmlSerializer(o.GetType()).Serialize(writer, o, ns);
            return doc;
        }

        public static XmlElement AsXmlElement<T>(this T o, XmlSerializerNamespaces ns = null, XmlSerializer serializer = null)
        {
            return o.AsXmlDocument(ns, serializer).DocumentElement;
        }

        public static T Deserialize<T>(this XmlElement element, XmlSerializer serializer = null)
        {
            using (var reader = new ProperXmlNodeReader(element))
                return (T)(serializer ?? new XmlSerializer(typeof(T))).Deserialize(reader);
        }
		
        /// <summary>
        /// Return an XmlSerializerNamespaces that disables the default xmlns:xsi and xmlns:xsd lines.
        /// </summary>
        /// <returns></returns>
        public static XmlSerializerNamespaces NoStandardXmlNamespaces()
        {
            var ns = new XmlSerializerNamespaces();
            ns.Add("", ""); // Disable the xmlns:xsi and xmlns:xsd lines.
            return ns;
        }
    }

    public class ProperXmlNodeReader : XmlNodeReader
    {
        // Bug fix from http://stackoverflow.com/questions/30102275/deserialize-object-property-with-stringreader-vs-xmlnodereader
        public ProperXmlNodeReader(XmlNode node)
            : base(node)
        {
        }

        public override string LookupNamespace(string prefix)
        {
            return NameTable.Add(base.LookupNamespace(prefix));
        }
    }

    public partial class AppDataType
    {

        private System.Xml.XmlElement[] anyField;

        private System.Xml.XmlAttribute[] anyAttrField;

        /// <remarks/>
        [System.Xml.Serialization.XmlAnyElementAttribute(Order = 1)]
        public System.Xml.XmlElement[] Any
        {
            get
            {
                return this.anyField;
            }
            set
            {
                this.anyField = value;
            }
        }

        [System.Xml.Serialization.XmlElement(Order = 0)]
        public string TestValue { get; set; }
    }

    public class SomeRequestType
    {
        public string StringValue { get; set; }
        public int[] IntList { get; set; }
    }

    public class TestClass
    {
        public static void Test()
        {
            try
            {
                TestInternal();
            }
            catch (Exception ex)
            {
                Debug.Assert(false, ex.ToString());
                throw;
            }
        }

        static void TestInternal()
        {
            var someRequestType = new SomeRequestType { StringValue = "string value", IntList = Enumerable.Range(0, 10).ToArray() };
            var appDataType = new AppDataType
            {
                TestValue = "test value",
                Any = new[] { someRequestType.AsXmlElement(XmlNodeExtensions.NoStandardXmlNamespaces()) },
            };

            var xml = appDataType.GetXml();
            Console.WriteLine(xml);
            var appDataBack = xml.LoadFromXML<AppDataType>();
            if (!(appDataType.Any.Select(e => e.OuterXml).SequenceEqual(appDataBack.Any.Select(e => e.OuterXml))))
            {
                throw new InvalidOperationException("!(appDataType.Any.Select(e => e.OuterXml).SequenceEqual(appDataBack.Any.Select(e => e.OuterXml)))");
            }
            if (!someRequestType.IntList.SequenceEqual(appDataBack.Any[0].Deserialize<SomeRequestType>().IntList) 
                || someRequestType.StringValue != appDataBack.Any[0].Deserialize<SomeRequestType>().StringValue)
            {
                throw new InvalidOperationException("!nested.IntList.SequenceEqual(appDataBack.Any[0].Deserialize<Nested>().IntList) || nested.StringValue != appDataBack.Any[0].Deserialize<Nested>().StringValue");
            }
        }
    }

    public static class XmlSerializationHelper
    {
        public static T LoadFromXML<T>(this string xmlString, XmlSerializer serializer = null)
        {
            T returnValue = default(T);

            using (StringReader reader = new StringReader(xmlString))
            {
                object result = (serializer ?? new XmlSerializer(typeof(T))).Deserialize(reader);
                if (result is T)
                {
                    returnValue = (T)result;
                }
            }
            return returnValue;
        }

        public static string GetXml<T>(this T obj, XmlSerializerNamespaces ns = null, XmlWriterSettings settings = null, XmlSerializer serializer = null)
        {
            using (var textWriter = new StringWriter())
            {
                settings = settings ?? new XmlWriterSettings() { Indent = true, IndentChars = "  " }; // For cosmetic purposes.
                using (var xmlWriter = XmlWriter.Create(textWriter, settings))
                    (serializer ?? new XmlSerializer(typeof(T))).Serialize(xmlWriter, obj, ns);
                return textWriter.ToString();
            }
        }
    }

	public class Program
	{
		public static void Main()
		{
			TestClass.Test();
		}
	}
;