2010-06-27 2 views
20

I Liste der Objekte List<TestObject> am Serialisierung und XmlSerializer erzeugt <ArrayOfTestObject> Attribut, möchte ich es umbenennen oder zu löschen.
Kann es mit dem Erstellen neuer Klasse, die Liste als Feld gekapselt getan werden?Wie <ArrayOf> XML-Attribut umbenennen, die nach der Serialisierung Liste der Objekte erzeugt

[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

Aktualisiert auf –

Antwort

24

Der zuverlässigste Weg ist eine äußerste DTO-Klasse zu deklarieren:

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

und serialisiert dass (das heißt die Liste in ein anderes Objekt setzen).


Sie können eine Wrapper-Klasse vermeiden, aber ich würde nicht:

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; } 
} 

Das Problem dabei ist, dass, wenn Sie benutzerdefinierte Attribute verwenden Sie sehr vorsichtig sein müssen Speichern und wiederverwenden Sie den Serializer, sonst erhalten Sie viele von dynamischen Baugruppen im Speicher geladen. Dies wird vermieden, wenn Sie einfach den Konstruktor XmlSerializer(Type) verwenden, da dieser intern automatisch zwischengespeichert wird.

+0

Marc traf den Nagel auf den Kopf. Ich habe einen ähnlichen Trick über http://stackoverflow.com/questions/3000934/return-xml-data-from-a-web-service/3001176#3001176 –

+0

So gibt es keine Möglichkeit zu vermeiden, eine andere Klasse zu verwenden? – ilann

+0

Es gibt einen besseren und einfacheren Weg, nur diese Frage: http://stackoverflow.com/questions/1237683/xml-serialization-of-listt-xml-root – Fedearne

0

eine andere Klasse erstellen wie:

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

     } 

Dann unten Code anwenden, während sealizing:

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

Das hatte keine Wirkung in meinem Fall. I _guess_ Der eingebaute Serializer sieht nur dann aus, wenn das zu serialisierende Objekt ein Kind von 'List' ist, um sein spezielles Benennungsschema anzuwenden. –

4

Ändern Sie die folgende Zeile aus:

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

An:

XmlRootAttribute root = new XmlRootAttribute("TestObjects");  

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

Es sollte funktionieren.