2012-02-20 7 views
9

Actualmente XmlSerializer produce la siguiente estructura:XmlSerializer reemplazar xsi: type al nodo nombre

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

¿Hay alguna manera de hacer que puso en nombre del tipo de nodo:

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

?

+0

¿Puede proporcionar el código de la clase desea realizar una serie? – Seb

Respuesta

0

Bueno, puede anular el nombre del elemento con XmlElement Attrribute, p.

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

si todavía pondrá el xsi: escribir sin embargo, y generar aún mayor confusión ...

Lo que se ve su clase como?

+0

No quiero anular el nombre del elemento. Quiero que el serializador establezca el Nombre igual al nombre de clase – SiberianGuy

+0

Eso es lo que esta respuesta intenta hacer. – Seb

+1

Hará eso. Por lo que yo sé, no puedes suprimir el tipeo, porque entonces nunca podrás deserializar. Si no necesita deserializar, entonces no está serializando, por lo tanto, debe dejar de molestarse con la serialización y simplemente escribir un método dumptoxml para su clase. La serialización tiene reglas, si no las sigue, no lo está haciendo ... –

24

Utilice la sobrecarga de constructor XmlElementAttribute(string elementName, Type type). Le permite reemplazar el nombre del elemento dado el tipo real encontrado en el miembro. Apila varios de estos si tienes varios tipos derivados.

Si está intentando serializar una colección genérica como List<Base> que podría contener instancias de Derivados, entonces use el XmlArrayItem de la misma manera.

Definición de esta manera también hace implícitamente el tipo derivado conocido, tanto un atributo XmlInclude No se requiere

definición de la muestra:

[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

¿Por qué la gente sigue diciendo "que nunca será capaz de deserializar ". Esto es definitivamente 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. Funciona simplemente bien! La serialización funciona de las tres maneras perfectamente. los objetos resultantes pueden no estar al 100% en ninguno de los lados, pero se DESESTACIONAN. Ser1 ignora el elemento de valor al deserializar ser2.xml Ser2 salta el propertuy Valor al deserializar ser1.xml

Lo único que rompe este modelo es:

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")); 

Este último se rompe, la Becuase la Serializador para BaseClass sigue el estándar de esquema (aunque es un valioso y el 99% del tiempo estándar deseado) de incluir el atributo xsi: type = "ChildClass" en el elemento. Ser3 no puede procesar ese tipo porque no está relacionado con ese tipo, especialmente si FlatClass existe en otro ensamblado a través de líneas WAN o LAN. Al igual que Honey-tejger, a XmlSerailizer NO LE PREOCUPAN los elementos o valores, siempre que pueda encontrarlos y nada en el esquema interrumpa el proceso. El atributo XSI: TYPE rompe el esquema.

Como, por ejemplo, cuando se usa WCF u otros sistemas basados ​​en comunicación XML si el Servicio tiene una clase llamada FlatClass, NO DESESTABLECERá una ChildClass que contenga el atributo xsi: type = "". Sin embargo, si no usa el serializador para BaseClass, deserializará exactamente el mismo XML sin ese atributo xsi: type.

Q.E.D. A menudo es beneficioso, necesario y DESEABLE, para NO incluya el atributo xsi: type.

Entonces, dicho esto, ¿hay alguna manera de tener un XmlSerializer creado para el tipo BaseClass y decirle NO incluir el atributo xsi: type al serializar un tipo secundario?

Gracias Jaeden "Sifo Dyas" al'Raec Ruiner

Cuestiones relacionadas