2017-06-02 2 views
0

J'ai une classe qui ressemble à ceci:Modification du nom d'un élément lors de la désérialisation de xml C#

[XmlType(TypeName = "rootType")] 
public class myClass 
{ 
    public Class1 class1; 
    public Class2 class2; 

    [XmlType(TypeName = "type1")] 
    public class class1 
    { ... class1 definition ...} 
    [XmlType(TypeName = "type2")] 
    public class class2 
    { ... class1 definition ...}  

} 

Quand je sérialiser, le xml résultant serait

<rootType> 
    <class1> 
     ... some stuff 
    <class1/> 
    <class2> 
     ... some stuff 
    <class2/> 
<rootType/> 

Cependant, mon problème ici est que ces décorations xmltype viennent d'être ajoutées à la classe, ce qui signifie que dans les versions précédentes (que les clients utilisent) le xml ressemblerait à quelque chose comme

<myClass> 
    <type1> 
     ... some stuff 
    <type1/> 
    <type2> 
     ... some stuff 
    <type2/> 
<myClass/> 

Existe-t-il un moyen de contrôler le processus de désérialisation (ou tout autre moyen permettant de le résoudre), si possible, et de pouvoir désérialiser ce fichier XML dans myClass avec ces décorations XmlType?

+0

Vous pouvez simplement transformer l'ancien xml et le nourrir dans votre nouveau désérialiseur. C'est probablement le plus facile. – Rook

+0

@Rook, je suis limité à ne pas transformer le vieux xml – Santi

+0

Mais comment xml peut-il être non-transformable? Vous pouvez le faire en mémoire lorsque vous chargez le fichier pour la première fois, ou vous pouvez le transformer en un fichier temporaire et le charger. – Rook

Répondre

0

Votre problème est complètement résolu.

Tout d'abord, lorsque vous créez un sérialiseur, ajoutez un paramètre XmlRootAttribute au nom souhaité. Ensuite, ajoutez le gestionnaire d'événements au sérialiseur.

var serializer = new XmlSerializer(typeof(myClass), new XmlRootAttribute("myClass")); 
serializer.UnknownElement += Serializer_UnknownElement; 

Le gestionnaire d'événements devrait ressembler à ceci:

void Serializer_UnknownElement(object sender, XmlElementEventArgs e) 
{ 
    myClass my = (myClass)e.ObjectBeingDeserialized; 

    if (e.Element.Name == "type1") 
    { 
     var ser = new XmlSerializer(typeof(myClass.Class1)); 
     using (var sr = new StringReader(e.Element.OuterXml)) 
      my.class1 = (myClass.Class1)ser.Deserialize(sr); 
    } 
    else if (e.Element.Name == "type2") 
    { 
     var ser = new XmlSerializer(typeof(myClass.Class2)); 
     using (var sr = new StringReader(e.Element.OuterXml)) 
      my.class2 = (myClass.Class2)ser.Deserialize(sr); 
    } 
} 

Pour utiliser comme toujours:

myClass my; 
using (var fs = new FileStream("test.xml", FileMode.Open)) 
    my = (myClass)serializer.Deserialize(fs); 

Il est censé fonctionner.

+0

Je vais essayer! – Santi

+0

Cela a fonctionné parfaitement, merci! – Santi