Can I make XmlSerializer ignore the namespace on deserialization?

C#.NetSerializationXml Serialization

C# Problem Overview


Can I make XmlSerializer ignore the namespace (xmlns attribute) on deserialization so that it doesn't matter if the attribute is added or not or even if the attribute is bogus? I know that the source will always be trusted so I don't care about the xmlns attribute.

C# Solutions


Solution 1 - C#

Yes, you can tell the XmlSerializer to ignore namespaces during de-serialization.

Define an XmlTextReader that ignores namespaces. Like so:

// 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 ""; }
    }
}

// helper class to omit XML decl at start of document when serializing
public class XTWFND  : XmlTextWriter {
    public XTWFND (System.IO.TextWriter w) : base(w) { Formatting= System.Xml.Formatting.Indented;}
    public override void WriteStartDocument () { }
}

Here's an example of how you would de-serialize using that TextReader:

public class MyType1 
{
    public string Label
    {
        set {  _Label= value; } 
        get { return _Label; } 
    }

    private int _Epoch;
    public int Epoch
    {
        set {  _Epoch= value; } 
        get { return _Epoch; } 
    }        
}



    String RawXml_WithNamespaces = @"
      <MyType1 xmlns='urn:booboo-dee-doo'>
        <Label>This document has namespaces on its elements</Label>
        <Epoch xmlns='urn:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'>0</Epoch>
      </MyType1>";


    System.IO.StringReader sr;
    sr= new System.IO.StringReader(RawXml_WithNamespaces);
    var s1 = new XmlSerializer(typeof(MyType1));
    var o1= (MyType1) s1.Deserialize(new NamespaceIgnorantXmlTextReader(sr));
    System.Console.WriteLine("\n\nDe-serialized, then serialized again:\n");
    XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
    ns.Add("urn", "booboo-dee-doo");
    s1.Serialize(new XTWFND(System.Console.Out), o1, ns);
    Console.WriteLine("\n\n");

The result is like so:

    <MyType1>
      <Label>This document has namespaces on its elements</Label>
      <Epoch>0</Epoch>
    </MyType1>

Solution 2 - C#

If you expect no namespace, but the input has namespaces, then you can set >Namespaces = false

on your XmlTextReader.

Solution 3 - C#

Exdended Wolfgang Grinfeld answer (w/o exception handling):

public static Message Convert(XmlDocument doc)
{
    Message obj;
    using (TextReader textReader = new StringReader(doc.OuterXml))
    {
        using (XmlTextReader reader = new XmlTextReader(textReader))
        {
            reader.Namespaces = false;
            XmlSerializer serializer = new XmlSerializer(typeof(Message));
            obj = (Message)serializer.Deserialize(reader);
        }
    }

    return obj;
}

Solution 4 - C#

Solved this by using XmlSerializer Deserialize to read from xml instead from stream. This way before xml is Deserialized, using Regex to remove xsi:type from the xml. Was doing this is Portable Class Library for Cross Platform, so did not had many other options :(. After this the deserialization seems to work fine.

Following code can help,

public static TClass Deserialize<TClass>(string xml) where TClass : class, new()
{
	var tClass = new TClass();

	xml = RemoveTypeTagFromXml(xml);

	var xmlSerializer = new XmlSerializer(typeof(TClass));
	using (TextReader textReader = new StringReader(xml))
	{
		tClass = (TClass)xmlSerializer.Deserialize(textReader);
	}
	return tClass;
}

public static string RemoveTypeTagFromXml(string xml)
{
	if (!string.IsNullOrEmpty(xml) && xml.Contains("xsi:type"))
	{
		xml = Regex.Replace(xml, @"\s+xsi:type=""\w+""", "");
	}
	return xml;
}

Solution 5 - C#

This does not ignore the namespace but instead expects it. I was attempting to do the same thing you were, but I've since added in validation using an XSD and the namespace is now required. So here is what I used to expect a namespace. https://stackoverflow.com/a/7730989/1856992

Solution 6 - C#

Why try to make the XmlSerializer forget how XML works? It's a fact of XML that two elements with the same name but different namespaces are different elements.

If you want to process XML that has no namespaces, then you should pre-process it to remove the namespaces, and then pass it to the serializer.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNotDanView Question on Stackoverflow
Solution 1 - C#CheesoView Answer on Stackoverflow
Solution 2 - C#Wolfgang GrinfeldView Answer on Stackoverflow
Solution 3 - C#klm_View Answer on Stackoverflow
Solution 4 - C#Abhimanyu ShuklaView Answer on Stackoverflow
Solution 5 - C#thinklargeView Answer on Stackoverflow
Solution 6 - C#John SaundersView Answer on Stackoverflow