2012-02-20 3 views
9

Attualmente XmlSerializer produce la seguente struttura:XmlSerializer sostituire xsi: type al nodo nome

<config> 
    <BaseType xsi:type="DerivedType1" /> 
    <BaseType xsi:type="DerivedType2" /> 
</config> 

C'è un modo per farlo mettere in nome del tipo di nodo:

<config> 
    <DerivedType1 /> 
    <DerivedType2 /> 
</config> 

?

+0

Potete fornire il codice della classe che si desidera serializzare? – Seb

risposta

0

Bene, è sufficiente sovrascrivere il nome dell'elemento con XmlElement Attrrib. Ad es.

[XmlElement("DerivedType1")] 
public BaseType : DerivedType1 {get;set;} 

se sarà ancora mettere il xsi: digitare però, e generare ancora più confusione ...

cosa fa il tuo sguardo di classe come?

+0

Non voglio sovrascrivere il nome dell'elemento. Voglio serializzatore per impostare il nome uguale al nome della classe – SiberianGuy

+0

Questo è ciò che questa risposta intende fare. – Seb

+1

Lo farà. Per quanto ne so, non si può sopprimere la digitazione, perché in tal caso non si sarà mai in grado di deserializzare. Se non hai bisogno di deserializzare, allora non stai serializzando, quindi dovresti smettere di messaggiare con la serializzazione e semplicemente scrivere un metodo dumptoxml per la tua classe. La serializzazione ha delle regole, se non le segui, non lo stai facendo ... –

24

Utilizzare il sovraccarico del costruttore XmlElementAttribute(string elementName, Type type). Permette di sostituire il nome dell'elemento dato il tipo effettivo trovato nel membro. Compilare più di questi insieme se si dispone di più tipi derivati.

Se si sta tentando di serializzare una raccolta generica come List<Base> che potrebbe contenere istanze di Derivato, utilizzare lo XmlArrayItem allo stesso modo.

Definire in questo modo anche rende implicitamente il tipo derivato noto, quindi un attributo XmlInclude non è richiesto

definizione del campione:

[XmlRoot] 
public class Data 
{ 
    [XmlElement("Derived1", typeof(Derived1))] 
    [XmlElement("Derived2", typeof(Derived2))] 
    public Base foo { get; set; } 
    [XmlArrayItem("Derived1", typeof(Derived1))] 
    [XmlArrayItem("Derived2", typeof(Derived2))] 
    public List<Base> fooList { get; set; } 
} 

public class Base { ... } 
public class Derived1 : Base { ... } 
public class Derived2 : Base { ... } 
0

perché la gente continui a dire "non sarai mai in grado per deserializzare. " Questo è definitivo FALSO.

public class BaseClass { 
    public string Name {get;set;} 
} 
[XmlRoot("BaseClass")] 
public class ChildClass : BaseClass { 
    public int Value {get;set;} 
} 
[XmlRoot("BaseClass")] 
public class FlatClass 
{ 
    public string Name {get;set;} 
    public int Value {get;set;} 
} 

XmlSerializer ser1 = new XmlSerializer(typeof(BaseClass)); 
XmlSerializer ser2 = new XmlSerializer(typeof(ChildClass)); 
XmlSerializer ser3 = new XmlSerializer(typeof(FlatClass)); 
ser1.Serialize(File.Open("ser1.xml", FileMode.Create), new BaseClass(){Name="Base"}); 
ser2.Serialize(File.Open("ser2.xml", FileMode.Create), new ChildClass(){Name="Child",Value = 1}); 

ser1.Deserialize(File.OpenRead("ser2.xml")); 
ser2.Deserialize(File.OpenRead("ser1.xml")); 
ser3.Deserialize(File.OpenRead("ser2.xml")); 

Boom. Funziona solo BENE !!!!! La serializzazione funziona perfettamente in tutte e tre le direzioni. gli oggetti risultanti potrebbero non essere al 100% su entrambi i lati, ma deserializza. Ser1 ignora l'elemento di valore quando la deserializzazione ser2.xml Ser2 salta la propertuy valore quando la deserializzazione ser1.xml

L'unica cosa che rompe questo modello è:

ser1.Serailize(File.Open("ser3.xml", FileMode.Create), new ChildClass(){Name = "Child2", Value = 2}); 
XmlSerialize ser3 = new XmlSerializer(typeof(FlatClass)); 
ser3.Deserialize(File.OpenRead("ser3.xml")); 

Quest'ultimo pause, becuase il il Serializzatore per BaseClass segue lo standard dello schema (sebbene sia uno standard valido e il 99% del tempo desiderato) di includere l'attributo xsi: type = "ChildClass" sull'elemento. Ser3 non può elaborare quel tipo perché non è realizzato per quel tipo, specialmente se FlatClass esiste in un altro assieme su linee WAN o LAN. Proprio come Honey-badger, XmlSerailizer NON CURA degli elementi o dei valori finché riesce a trovarli e nulla nello schema interrompe il processo. L'attributo XSI: TYPE interrompe lo schema.

Come, ad esempio, quando si utilizza WCF o altri sistemi di comunicazione XML se il Servizio ha una classe chiamata FlatClass, NON DESERIALIZZA una ChildClass che contiene l'attributo xsi: type = "". Tuttavia, se non si utilizza il serializzatore per BaseClass, verrà deserializzato esattamente lo stesso XML senza quell'attributo xsi: type.

Q.E.D. Spesso è utile, necessario e DISPONIBILE, per NON includere l'attributo xsi: type.

Quindi con ciò detto c'è un modo per avere un XmlSerializer creato per il tipo BaseClass e dirgli di NON includere l'attributo xsi: type durante la serializzazione di un tipo figlio?

Grazie Jaeden "Sifo Dyas" al'Raec Ruiner