2014-12-09 3 views
3

Я имею дело с API, который иногда меняет пространства имен на XML, который я получаю. Структура XML остается прежней. Мне нужно десериализовать XML в строго типизированную модель.Как десериализовать XML, когда вы не знаете пространство имен?

Как выполнить десериализацию независимо от того, какое пространство имен находится в XML?

я использовал модель, как это:

[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; } 
} 

Я пытаюсь десериализации некоторые XML в этой модели с кодом, как это:

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

Моя проблема заключается в том, что каждый так часто, пространство имен на XML я получаю изменения. Я мог бы начать получать XML, как это:

<TestModel xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/UnknownNamespace2"> 
    <TestModelChildren> 
     ... 
    </TestModelChildren> 
</TestModel> 

Я не хочу, чтобы перекомпилировать код каждый раз, когда это изменение имен происходит. Как мне с этим справиться?

ответ

3

Я смог решить проблему, передав пространство имен в XmlSerializer в качестве пространства имен по умолчанию. Я могу вырвать пространство имен из XDocument, чтобы сделать это.

Моя новая модель будет выглядеть следующим образом без имен, указанных:

[Serializable, XmlRoot(ElementName = "TestModel")] 
public class TestModel 
{ 
    public TestModel() 
    { 
     TestElements = new List<TestModelChildren>(); 
    } 

    [XmlElement("TestModelChildren")] 
    public List<TestModelChildren> TestElements { get; set; } 
} 

Мой код десериализации XML будет выглядеть следующим образом:

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

Это работает для меня.