2010-06-27 13 views
20

sto serializzazione Elenco di oggetti List<TestObject> , e XmlSerializer genera <ArrayOfTestObject> attributo, voglio rinominarlo o rimuoverlo.
Si può fare con la creazione di una nuova classe che elenca incapsulato come campo?Come rinominare <ArrayOf> attributo XML che ha generato dopo la serializzazione Elenco di oggetti

[XmlRoot("Container")]  
public class TestObject 
{ 
    public TestObject() { }       
    public string Str { get; set; }       
} 

List<TestObject> tmpList = new List<TestObject>(); 

TestObject TestObj = new TestObject(); 
TestObj.Str = "Test"; 

TestObject TestObj2 = new TestObject(); 
TestObj2.Str = "xcvxc"; 

tmpList.Add(TestObj); 
tmpList.Add(TestObj2); 


XmlWriterSettings settings = new XmlWriterSettings(); 
settings.OmitXmlDeclaration = true; 
settings.Indent = true; 
XmlSerializer serializer = new XmlSerializer(typeof(List<TestObject>)); 

using (XmlWriter writer = XmlWriter.Create(@"C:\test.xml", settings)) 
{    
    XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces(); 
    namespaces.Add(string.Empty, string.Empty); 
    serializer.Serialize(writer, tmpList, namespaces);        
} 


<ArrayOfTestObject> 
    <TestObject> 
    <Str>Test</Str> 
    </TestObject> 
    <TestObject> 
    <Str>xcvxc</Str> 
    </TestObject> 
</ArrayOfTestObject> 
+0

Aggiornamento re commento –

risposta

24

Il modo più affidabile è quello di dichiarare un esterno classe DTO:

[XmlRoot("myOuterElement")] 
public class MyOuterMessage { 
    [XmlElement("item")] 
    public List<TestObject> Items {get;set;} 
} 

e serializzare che (vale a dire mettere la vostra lista in un altro oggetto).


È possibile evitare una classe wrapper, ma non vorrei:

class Program 
{ 
    static void Main() 
    { 
     XmlSerializer ser = new XmlSerializer(typeof(List<Foo>), 
      new XmlRootAttribute("Flibble")); 
     List<Foo> foos = new List<Foo> { 
      new Foo {Bar = "abc"}, 
      new Foo {Bar = "def"} 
     }; 
     ser.Serialize(Console.Out, foos); 
    } 
} 

public class Foo 
{ 
    public string Bar { get; set; } 
} 

Il problema con questo è che quando si utilizza attributi personalizzati è necessario essere molto attenti per memorizzare e riutilizzare il serializzatore, altrimenti si ottengono lotti di di assiemi dinamici caricati in memoria. Ciò viene evitato se si utilizza semplicemente il costruttore XmlSerializer(Type), poiché esso lo memorizza automaticamente internamente.

+0

Marc ha colpito l'unghia sulla testa. Ho fatto un trucco simile su http://stackoverflow.com/questions/3000934/return-xml-data-from-a-web-service/3001176#3001176 –

+0

Quindi non c'è modo di evitare l'uso di un'altra classe? – ilann

+0

C'è un modo migliore e più semplice, basta questa domanda: http://stackoverflow.com/questions/1237683/xml-serialization-of-listt-xml-root – Fedearne

0

creare un'altra classe come:

 [XmlRoot("TestObjects")] 
     public class TestObjects: List<TestObject> 
     { 

     } 

Applicare quindi qui di seguito il codice mentre sealizing:

  XmlSerializer serializer = new XmlSerializer(typeof(TestObjects)); 
      MemoryStream memStream = new MemoryStream(); 
      serializer.Serialize(memStream, tmpList); 
+0

Questo non ha avuto alcun effetto nel mio caso. I_guess_ il serializzatore integrato guarda solo se l'oggetto da serializzare è figlio di 'List' per applicare il suo schema di denominazione speciale. –

4

modificare la riga seguente da:

XmlSerializer serializer = new XmlSerializer(typeof(List<TestObject>)); 

A:

XmlRootAttribute root = new XmlRootAttribute("TestObjects");  

XmlSerializer serializer = new XmlSerializer(typeof(List<TestObject>), root); 

Dovrebbe funzionare.

Problemi correlati