https://stackoverflow.com/questions/64679585/c-sharp-deserialize-xml-while-ignoring-namespace

CSharp · Console

/Program.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Xml.Serialization;
using System.Xml;
using System.Xml.Linq;
using System.IO;
using System.Data;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO.Compression;
using System.Reflection;

using NUnit.Framework; //NUnit.Framework.AssertionException

//https://stackoverflow.com/questions/64679585/c-sharp-deserialize-xml-while-ignoring-namespace

	public class Root
	{
		public SomeClass IWantThis { get; set; }
	}

	public class SomeClass
	{
		public string Value { get; set; }
	}
	
    public class TestClass
    {
        public static void Test()
        {
			foreach (var xml in GetXml())
			{
				using (var textReader = new StringReader(xml))
				{
					var loadedSomeClassXml = XmlExtensions.GetObjectFromXml<SomeClass>(textReader, "IWantThis", "", true);
					Assert.AreEqual("hello", loadedSomeClassXml?.Value);
					Console.WriteLine("{0} deserialized successfully.", loadedSomeClassXml);
				}
			}
        }
		
		static IEnumerable<string> GetXml()
		{
			return new []
			{
				@"<Root xmlns=""ignoreThisNamespace"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
  <IWantThis>
    <Value>hello</Value>
  </IWantThis>
</Root>",
				@"<a:Root xmlns:a=""ignoreThisNamespace"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
  <a:IWantThis>
    <a:Value>hello</a:Value>
  </a:IWantThis>
</a:Root>",
			};
		}
    }

	public static partial class XmlExtensions
	{
		public static T GetObjectFromXml<T>(string path, string localName, string namespaceURI, bool ignoreNamespaces = false)
		{
			using (var textReader = new StreamReader(path))
				return GetObjectFromXml<T>(textReader, localName, namespaceURI);
		}
		
		public static T GetObjectFromXml<T>(TextReader textReader, string localName, string namespaceURI, bool ignoreNamespaces = false)
		{
			using (var xmlReader = ignoreNamespaces ? new NamespaceIgnorantXmlTextReader(textReader) : XmlReader.Create(textReader))
				return GetObjectFromXml<T>(xmlReader, localName, namespaceURI);
		}
		
		public static T GetObjectFromXml<T>(XmlReader reader, string localName, string namespaceURI)
		{
			while (reader.Read())
			{
				if (reader.NodeType == XmlNodeType.Element && reader.LocalName == "IWantThis" && reader.NamespaceURI == namespaceURI)
				{
					var serializer = XmlSerializerFactory.Create(typeof(T), localName, namespaceURI);
					using (var subReader = reader.ReadSubtree())
						return (T)serializer.Deserialize(subReader);
				}
			}
			// Or throw an exception?
			return default(T);
		}
	}

	// This class copied from this answer https://stackoverflow.com/a/873281/3744182
	// To https://stackoverflow.com/questions/870293/can-i-make-xmlserializer-ignore-the-namespace-on-deserialization
	// By https://stackoverflow.com/users/48082/cheeso
	// helper class to ignore namespaces when de-serializing
	public class NamespaceIgnorantXmlTextReader : XmlTextReader
	{
		public NamespaceIgnorantXmlTextReader(System.IO.TextReader reader): base(reader) { }

		public override string NamespaceURI { get { return ""; } }
	}

    public static class XmlSerializerFactory
    {
        // To avoid a memory leak the serializer must be cached.
        // https://stackoverflow.com/questions/23897145/memory-leak-using-streamreader-and-xmlserializer
        // This factory taken from 
        // https://stackoverflow.com/questions/34128757/wrap-properties-with-cdata-section-xml-serialization-c-sharp/34138648#34138648

        readonly static Dictionary<Tuple<Type, string, string>, XmlSerializer> cache;
        readonly static object padlock;

        static XmlSerializerFactory()
        {
            padlock = new object();
            cache = new Dictionary<Tuple<Type, string, string>, XmlSerializer>();
        }

        public static XmlSerializer Create(Type serializedType, string rootName, string rootNamespace)
        {
            if (serializedType == null)
                throw new ArgumentNullException();
            if (rootName == null && rootNamespace == null)
                return new XmlSerializer(serializedType);
            lock (padlock)
            {
                XmlSerializer serializer;
                var key = Tuple.Create(serializedType, rootName, rootNamespace);
                if (!cache.TryGetValue(key, out serializer))
                {
                    cache[key] = serializer = new XmlSerializer(serializedType, new XmlRootAttribute { ElementName = rootName, Namespace = rootNamespace });
                }
                return serializer;
            }
        }
    }

	public class Program
	{
		public static void Main()
		{
			Console.WriteLine("Environment version: {0} ({1})", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , GetNetCoreVersion());
			Console.WriteLine();

			try
			{
				TestClass.Test();
			}
			catch (Exception ex)
			{
				Console.WriteLine("Failed with unhandled exception: ");
				Console.WriteLine(ex);
				throw;
			}
		}
		
		public static string GetNetCoreVersion()
		{
			//https://techblog.dorogin.com/how-to-detect-net-core-version-in-runtime-ecd65ad695be
			//
			var assembly = typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly;
			var assemblyPath = assembly.CodeBase.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
			int netCoreAppIndex = Array.IndexOf(assemblyPath, "Microsoft.NETCore.App");
			if (netCoreAppIndex > 0 && netCoreAppIndex < assemblyPath.Length - 2)
				return assemblyPath[netCoreAppIndex + 1];
			return null;
		}
	}
;