Reputation: 1056
I am dealing with an API that occasionally changes the namespaces on the XML that I receive. The XML structure remains the same. I need to deserialize the XML into a strongly typed model.
How do I perform the deserialization regardless of what namespace is on the XML?
I was using a model like this:
[Serializable, XmlRoot(ElementName = "TestModel", Namespace = "http://schemas.datacontract.org/UnknownNamespace1")]
public class TestModel
{
public TestModel()
{
TestElements = new List<TestModelChildren>();
}
[XmlElement("TestModelChildren")]
public List<TestModelChildren> TestElements { get; set; }
}
I try to deserialize some XML into that model with code like this:
public TestModel DeserializeIt(XDocument xDoc)
{
TestModel result;
var serializer = new XmlSerializer(typeof(TestModel));
using(var sr = new StringReader(xDoc.ToString()))
{
result = (TestModel)serializer.Deserialize(sr);
}
return result;
}
My problem is that every so often, the namespace on the XML I am receiving changes. I might start getting XML like this:
<TestModel xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/UnknownNamespace2">
<TestModelChildren>
...
</TestModelChildren>
</TestModel>
I don't want to have to recompile my code every time this namespace change happens. How do I deal with it?
Upvotes: 3
Views: 152
Reputation: 1056
I was able to solve the problem by passing the namespace in to the XmlSerializer as a default namespace. I can pluck the namespace off of the XDocument to do this.
My new model would look like this without a namespace specified:
[Serializable, XmlRoot(ElementName = "TestModel")]
public class TestModel
{
public TestModel()
{
TestElements = new List<TestModelChildren>();
}
[XmlElement("TestModelChildren")]
public List<TestModelChildren> TestElements { get; set; }
}
My code to deserialize the XML would look like this:
public TestModel DeserializeIt(XDocument xDoc)
{
TestModel result;
var serializer = new XmlSerializer(typeof(TestModel), xDoc.Root.Name.Namespace.ToString());
using(var sr = new StringReader(xDoc.ToString()))
{
result = (TestModel)serializer.Deserialize(sr);
}
return result;
}
This has been working for me.
Upvotes: 3