2015-06-02 2 views
1

Итак, у меня есть базовый проект и несколько модифицированных версий. BaseProject содержит класс BaseClass,десериализация, специфичная для версии XML

namespace BaseProject.SomeClasses{ 
    public abstract class BaseClass{ 
    //... 
    } 
} 

в то время как каждая из версий содержит несколько наследников BaseClass - F.E. ProjectOne:

namespace BaseProject.VersionOne.SomeClasses{ 
    public class InheritorClass : BaseClass{ 
    //Some logic here... 
    } 
} 

и ProjectTwo:

namespace BaseProject.VersionTwo.SomeClasses{ 
    public class InheritorClass : BaseClass{ 
    //Some different logic here... 
    } 
} 

Единственное, что отличает это имя пространства имен.

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

... 
<BaseClass xsi:type="InheritorClass"> <!-- From VersionOne --> 
    <PropOne></PropOne> 
    <PropTwo></PropTwo> 
    <PropThree></PropThree> 
    <!-- ... --> 
</BaseClass> 
<BaseClass xsi:type="InheritorClass"> <!-- From VersionTwo --> 
    <PropFour></PropFour> 
    <PropFive></PropFive> 
    <PropSix></PropSix> 
    <!-- ... --> 
</BaseClass> 
... 

Есть ли способ десериализации этого XML (которая содержит экземпляры наследников из обеих версий) в IEnumerable<BaseClass>?

+0

Вам нужно квалифицировать свои элементы с заданным пространством имен –

+0

@MartinCh, нормально, но как связать пространство имен xml и пространство имен C#, если я могу получить доступ к последнему только во время выполнения? –

+0

Я не получаю логики того, чего вы хотите достичь. Базовый класс - это родительский объект - ваши наследственные классы - наследуются - специализации - вы не можете отбросить ребенка обратно родителям без потери персонала, который был добавлен в childs –

ответ

0

Вы должны применить атрибут [XmlTypeAttribute(name)] к вашим производным классам неоднозначность xst:type имена:

namespace BaseProject.VersionOne.SomeClasses 
{ 
    [XmlType("VersionOneInheritorClass")] 
    public class InheritorClass : BaseClass 
    { 
     public string VersionOneProperty { get; set; } // For instance 
    } 
} 

и

namespace BaseProject.VersionTwo.SomeClasses 
{ 
    [XmlType("VersionTwoInheritorClass")] 
    public class InheritorClass : BaseClass 
    { 
     public string VersionTwoProperty { get; set; } // For instance 
    } 
} 

Тогда ваш XML будет выглядеть следующим образом, и может быть серийно и десериализован без потери информации:

<BaseClass xsi:type="VersionOneInheritorClass"> 
    <VersionOneProperty>one</VersionOneProperty> 
</BaseClass> 
<BaseClass xsi:type="VersionTwoInheritorClass"> 
    <VersionTwoProperty>two</VersionTwoProperty> 
</BaseClass> 

Кстати, если вы построение XmlSerializer с помощью XmlSerializer (Type, Type[]) конструктора для добавления в ваших открытых производных типов, вы должны cache the serializer in a static cache somewhere, иначе вы будете иметь ужасную утечку ресурсов.

+0

Ну, я также немного настроил Serializer, и это сработало отлично! Спасибо! –

0

Пространство имен класса не должно иметь значения. См. XML-файл, генерируемый этим кодом.

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

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     const string FILENAME = @"c:\temp\test.xml"; 
     static void Main(string[] args) 
     { 
      Root root = new Root() 
      { 
       baseClass = new List<BaseClass>(){ 
        new InheritorClass1(){ name = "class1"}, 
        new InheritorClass2(){ name = "class2"} 
       } 
      }; 
      XmlSerializer serializer = new XmlSerializer(typeof(Root)); 

      StreamWriter writer = new StreamWriter(FILENAME); 
      serializer.Serialize(writer, root); 
      writer.Flush(); 
      writer.Close(); 
      writer.Dispose(); 

      XmlSerializer xs = new XmlSerializer(typeof(Root)); 
      XmlTextReader reader = new XmlTextReader(FILENAME); 
      Root newRoot = (Root)xs.Deserialize(reader); 
     } 
    } 
    [XmlRoot("Root")] 
    public class Root 
    { 
     [XmlElement("BaseClass")] 
     public List<BaseClass> baseClass { get; set; } 
    } 
    [XmlRoot("BaseClass")] 
    [XmlInclude(typeof(InheritorClass1))] 
    [XmlInclude(typeof(InheritorClass2))] 
    public class BaseClass 
    { 
     [XmlElement("name")] 
     public string name { get; set; }  

    } 
    [XmlRoot("InheritorClass1")] 
    public class InheritorClass1 : BaseClass 
    { 
    } 

    [XmlRoot("InheritorClass2")] 
    public class InheritorClass2 : BaseClass 
    { 
    } 

} 
​ 
Смежные вопросы