www org mapwindows mapwindow español c# xml xml-serialization

c# - org - ¿Cómo puedo cambiar el nombre de los nombres de clase a través de atributos Xml?



mapwindows 5 (5)

Solución: use [XmlType (TypeName = "g")]

XmlRoot solo funciona con nodos raíz XML según la documentación (y lo que esperaría, dado que su nombre incluye la raíz ).

No pude obtener ninguna de las otras respuestas para trabajar, así que seguí cavando ...

En cambio, descubrí que XmlTypeAttribute (es decir, [XmlType] ) y su propiedad TypeName hacen un trabajo similar para clases / objetos que no son raíz .

p.ej

[XmlType(TypeName="g")] class Song { public string Artist; public string SongTitle; }

Suponiendo que lo aplique a las otras clases, por ejemplo:

[XmlType(TypeName="a")] class Artist { ..... } [XmlType(TypeName="s")] class SongTitle { ..... }

Esto generará lo siguiente exactamente como se requiere en la pregunta :

<g> <a>Britney Spears</a> <s>I Did It Again</s> </g>

Lo he usado en varios proyectos de producción y no encontré problemas con él.

Supongamos que tengo una clase XML serializable llamada Song :

[Serializable] class Song { public string Artist; public string SongTitle; }

Para ahorrar espacio (y también semi-ofuscar el archivo XML), decido cambiar el nombre de los elementos xml:

[XmlRoot("g")] class Song { [XmlElement("a")] public string Artist; [XmlElement("s")] public string SongTitle; }

Esto producirá un resultado XML como este:

<Song> <a>Britney Spears</a> <s>I Did It Again</s> </Song>

Quiero renombrar / reasignar el nombre de la clase / objeto también. Digamos, en el ejemplo anterior, deseo cambiar el nombre de la clase Song a g . Para que el xml resultante se vea así:

<g> <a>Britney Spears</a> <s>I Did It Again</s> </g>

¿Es posible cambiar el nombre de los nombres de clase a través de xml-attributes ?

No deseo crear / recorrer el DOM manualmente, así que me preguntaba si se podría lograr a través de un decorador.

¡Gracias por adelantado!

ACTUALIZACIÓN: ¡Ups! ¡Esta vez realmente lo hice de nuevo! Olvidé mencionar: de hecho estoy serializando una lista de objetos Song en el XML.

Aquí está el código de serialización:

public static bool SaveSongs(List<Song> songs) { XmlSerializer serializer = new XmlSerializer(typeof(List<Song>)); using (TextWriter textWriter = new StreamWriter("filename")) { serializer.Serialize(textWriter, songs); } }

Y aquí está la salida XML:

<?xml version="1.0" encoding="utf-8"?> <ArrayOfSong> <Song> <a>Britney Spears</a> <s>Oops! I Did It Again</s> </Song> <Song> <a>Rihanna</a> <s>A Girl Like Me</s> </Song> </ArrayOfSong>

Aparentemente, el atributo XmlRoot () no cambia el nombre del objeto en un contexto de lista.

¿Me estoy perdiendo de algo?


Si este es el elemento raíz del documento, puede usar [XmlRoot("g")] .

Aquí está mi respuesta actualizada basada en su aclaración. El grado de control que está solicitando no es posible sin una clase de ajuste. Este ejemplo utiliza una clase SongGroup para envolver la lista para que pueda dar nombres alternativos a los elementos dentro de.

using System; using System.Collections.Generic; using System.IO; using System.Xml.Serialization; public class SongGroup { public SongGroup() { this.Songs = new List<Song>(); } [XmlArrayItem("g", typeof(Song))] public List<Song> Songs { get; set; } } public class Song { public Song() { } [XmlElement("a")] public string Artist { get; set; } [XmlElement("s")] public string SongTitle { get; set; } } internal class Test { private static void Main() { XmlSerializer serializer = new XmlSerializer(typeof(SongGroup)); SongGroup group = new SongGroup(); group.Songs.Add(new Song() { Artist = "A1", SongTitle = "S1" }); group.Songs.Add(new Song() { Artist = "A2", SongTitle = "S2" }); using (Stream stream = new MemoryStream()) using (StreamWriter writer = new StreamWriter(stream)) { serializer.Serialize(writer, group); stream.Seek(0, SeekOrigin.Begin); using (StreamReader reader = new StreamReader(stream)) { Console.WriteLine(reader.ReadToEnd()); } } } }

Esto tiene el efecto secundario de generar un elemento interno más que representa la lista en sí. En mi sistema, la salida se ve así:

<?xml version="1.0" encoding="utf-8"?> <SongGroup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Songs> <g> <a>A1</a> <s>S1</s> </g> <g> <a>A2</a> <s>S2</s> </g> </Songs> </SongGroup>


Use XmlElementAttribute: [XmlRoot("g")]

[Serializable] [XmlRoot(ElementName="g")] class Song { public string Artist; public string SongTitle; }

Deberia trabajar.


Verifica el atributo XmlRoot.

La documentación se puede encontrar aquí: http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlrootattribute(v=VS.90).aspx

[XmlRoot(Namespace = "www.contoso.com", ElementName = "MyGroupName", DataType = "string", IsNullable=true)] public class Group

ACTUALIZACIÓN: Acabo de probar y funciona perfectamente en VS 2008. Este código:

[XmlRoot(ElementName = "sgr")] public class SongGroup { public SongGroup() { this.Songs = new List<Song>(); } [XmlElement(ElementName = "sgs")] public List<Song> Songs { get; set; } } [XmlRoot(ElementName = "g")] public class Song { [XmlElement("a")] public string Artist { get; set; } [XmlElement("s")] public string SongTitle { get; set; } }

Productos:

<?xml version="1.0" encoding="utf-8"?> <sgr xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www .w3.org/2001/XMLSchema"> <sgs> <a>A1</a> <s>S1</s> </sgs> <sgs> <a>A2</a> <s>S2</s> </sgs> </sgr>


[XmlRoot("g")] class Song { }

Debería hacer el truco