2017-10-19 19 views
1

J'avais travaillé avec la désérialisation et je suis resté bloqué.C#. Désérialisation en les mêmes types en fonction de l'attribut

Il y a mes cours:

public class Parent 
{ 
    public List<Child> child {get;set} 
} 

public class Child 
{ 
    some properties 
} 

public class Child1 : Child 
{ 
    some properties 
} 

public class Child2 : Child 
{ 
    some properties 
} 

Et je xml:

<Parent> 
    <Child AttribName="TypeOne"> 
    </Child> 
    <Child AttribName="TypeTwo"> 
    </Child> 
</Parent> 

Comment puis-je utiliser des attributs [Xml] pour le faire? J'ai besoin sur la base d'un attribut List<Child> (Enfant1 ou Enfant2, selon attrute nomAttribut) dans Parent

+0

Est-xml nécessaire pour apparaître dans ce format? Ou avez-vous la possibilité de dicter à quoi cela devrait ressembler? – JuanR

+0

comme une note de côté: une partie de la * raison * que ce n'est pas un scénario pris en charge est que * xsd * ne supporte pas cela –

+0

- Xml reqired ce format – snowil

Répondre

0

Vous pouvez utiliser le lecteur XML personnalisé comme celui-ci:

public class CustomXmlReader : XmlTextReader 
{ 
    public CustomXmlReader(string url) : base(url) { } 

    public override string GetAttribute(string localName, string namespaceURI) 
    { 
     if (namespaceURI == "http://www.w3.org/2001/XMLSchema-instance" && localName == "type") 
     { 
      if (base.LocalName == "Child") 
      { 
       var attr = base.GetAttribute("AttribName"); 

       if (attr == "TypeOne") 
        return "Child1"; 
       if (attr == "TypeTwo") 
        return "Child2"; 
      } 
     } 
     return base.GetAttribute(localName, namespaceURI); 
    } 
} 

Ajouter des attributs à la classe de base:

[XmlInclude(typeof(Child1))] 
[XmlInclude(typeof(Child2))] 
public class Child 

Exemple d'utilisation:

var xs = new XmlSerializer(typeof(Parent)); 

Parent parent; 

using (var xmlReader = new CustomXmlReader("test.xml")) 
    parent = (Parent)xs.Deserialize(xmlReader); 
+0

Génial! Ça marche – snowil

1

XmlSerializer ne supporte pas discriminateurs; seulement le nom de l'élément. Donc, vous pouvez utiliser XmlSerializer pour ce - mais pas votre scénario:

<Parent> 
    <ChildTypeOne> 
    </ChildTypeOne> 
    <ChildTypeTwo> 
    </ChildTypeTwo> 
</Parent> 

Options:

  • deserialize manuellement
  • transformer le XML avant désérialisation
  • changer simplement le format xml
+0

J'ai la structure forte et grande de xml. Transformer avant la sérialisation sera une opération très lourde. Il semble que j'ai besoin d'écrire une sérialisation personnalisée. Merci – snowil

0

Dans mon cas avec forte xm Format I et très gros fichiers Je n'ai qu'une seule solution: la sérialisation personnalisée.