2010-06-27 3 views
20

Mam identyfikatorów seryjnych Lista obiektów List<TestObject> i XmlSerializer generuje <ArrayOfTestObject> atrybut, chcę zmienić jego nazwę lub usunąć go.
Czy można to zrobić, tworząc nową klasę z listą zamkniętą jako pole?Jak zmienić nazwę <ArrayOf> atrybut XML wygenerowany po szeregowania Lista obiektów

[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

Zaktualizowano komentarz –

Odpowiedz

24

Najpewniejszym sposobem jest zadeklarować zewnętrzną klasy DTO:

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

i szeregować że (tj umieścić swoją listę do innego obiektu).


Ty może uniknąć klasy otoki, ale nie będę:

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

problemem z tego jest to, że podczas korzystania z niestandardowych atrybutów trzeba być ostrożnym bardzo do przechowywania i ponownego użycia serializera, w przeciwnym razie otrzymasz wiele dynamicznych złożeń załadowanych do pamięci. Unika się tego, jeśli używasz konstruktora XmlSerializer(Type), ponieważ buforuje to wewnętrznie automatycznie.

+0

Marc uderzył w gwóźdź w głowę. Zrobiłem podobny trik na http://stackoverflow.com/questions/3000934/return-xml-data-from-a-web-service/3001176#3001176 –

+0

Więc nie ma sposobu, aby uniknąć użycia innej klasy? – ilann

+0

Istnieje lepszy i łatwiejszy sposób, po prostu se to pytanie: http://stackoverflow.com/questions/1237683/xml-serialization-of-listt-xml-root – Fedearne

0

Tworzenie innej klasy, takich jak:

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

     } 

następnie zastosować poniższy kod podczas sealizing:

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

Nie miało to żadnego wpływu w moim przypadku. I _guess_ wbudowany serializer sprawdza tylko, czy obiekt do serializacji jest potomkiem 'List' w celu zastosowania swojego specjalnego schematu nazewnictwa. –

4

zmienić następujące linie z:

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

Do:

XmlRootAttribute root = new XmlRootAttribute("TestObjects");  

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

Powinien działać.

Powiązane problemy