2017-03-13 5 views
0

Ich versuche, eine Xml-Datei mit dem XmlSerializer zu deserialisieren. Ein Teil meiner Datei sieht wie folgt aus:XML-Deserialisierung einer verschachtelten Liste C#

<bla> 
    <ListOfListOfTest> 
     <ListOfTest> 
       <Test>  
       </Test>   
     </ListOfTest>   
    </ListOfListOfTest> 
</bla> 

ich verschiedene Arten versucht, aber es funktioniert nicht.

Mein erster Versuch sah aus wie:

public class bla 
    { 
     public bla() 
     { 
      ListOfListOfTest = new List<List<Test>>(); 
     } 
     [...] 
     public List<List<Test>> ListOfListOfTest{ get; set; }    
    } 

-> funktioniert nicht.

Zweiter Versuch:

public class bla 
    { 
     public bla() 
     { 
      ListOfListOfTest = new List<List<Test>>(); 
     } 
     [..] 
     public List<List<Test>> ListOfListOfTest { get; set; } 

     [XmlArrayItemAttribute] 
     public List<List<Test>> listOfListOfTest { get { return ListOfListOfTest ; } } 
    } 

-> fehlgeschlagen

auch

Dritter Versuch:

public class bla 
    { 
     public bla() 
     { 
      ListOfListOfTest = new List<Foo>(); 
     } 
     [...] 
     public List<Foo> ListOfListOfTest { get; set; } 

    } 


    public class Foo 
    { 
     public Foo() 
     { 
      ListOfTest = new List<Test>(); 
     } 
     public List<Test> ListOfTest { get; set; } 
    } 

-> ist fehlgeschlagen ...

konnte nicht bedeutet, dass die XmlSerializer nicht füllen Sie die List während serializer.Deserialize(). Ich bekomme immer eine List mit Null Elementen drin.

Was mache ich falsch?

Dank für Ihre Mühe

+2

Sie sich mit dem 'XmlElement' vertraut machen sollte,' XmlArray' und 'XmlArrayItem' Attribute. Der XmlSerializer benötigt offensichtlich einige Meta-Informationen, um zu verstehen, was wo hingehört. –

+0

Welche Elemente könnten wiederholt werden? alle von ihnen? nur 'Test'? –

+0

XmlArray und XmlArrayItem waren die fehlenden Liks. vielen dank! – dertrautmann

Antwort

0

So etwas wie das?

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Xml.Serialization; 

class Program { 
    static void Main() { 
     var xml = @"<bla> 
    <ListOfListOfTest> 
     <ListOfTest> 
       <Test>  
       </Test>   
     </ListOfTest>   
    </ListOfListOfTest> 
</bla>"; 
     var bar = (Bar)new XmlSerializer(typeof(Bar)).Deserialize(new StringReader(xml)); 
     Console.WriteLine(bar.Lists.Sum(_ => _.Items.Count)); // 1 
    } 
} 
[XmlRoot("bla")] 
public class Bar { 
    [XmlArray("ListOfListOfTest")] 
    [XmlArrayItem("ListOfTest")] 
    public List<Foo> Lists { get; } = new List<Foo>(); 
} 
public class Foo { 
    [XmlElement("Test")] 
    public List<Test> Items { get; } = new List<Test>(); 
} 
public class Test { } 

Das tatsächliche Layout hängt davon ab, welche Elemente dupliziert werden könnten, und ob Sie brauchen, um die genaue Organisation in der Lage sein zu reproduzieren (vs nur all Test Artikel zu wollen). In dem obigen Code wird nicht erwartet, dass ListOfListOfTest dupliziert wird, aber es kann eine beliebige Anzahl von ListOfTest oder Test Elementen geben.

+0

funktioniert einwandfrei. Vielen Dank ! – dertrautmann

1

in den Griff zu bekommen, wie die XML, wenn sie richtig deserialisiert aussehen wird, kopieren Sie Ihre XML:

<bla> 
    <ListOfListOfTest> 
     <ListOfTest> 
       <Test>  
       </Test>   
     </ListOfTest>   
    </ListOfListOfTest> 
</bla> 

eine Klasse in C# erstellen. Klicken Sie oben auf "Bearbeiten", dann auf "Inhalte einfügen" und dann auf "XML als Klassen einfügen", während sich der Cursor in der Klasse befindet. Visual Studio wird den XML-Code für Sie korrekt deserialisieren und die erforderlichen Klassen erstellen. Verwenden Sie dies, um zu vergleichen, was Sie dachten und was Sie tatsächlich benötigen, um selbst zu klären, wie Deserialisierung funktionieren sollte.

+0

Wow. das ist ziemlich cool. Jetzt frage ich mich, warum ich so viel Zeit damit verbracht habe, es manuell zu machen -_- – dertrautmann

+0

Ich fühlte mich genauso, als ich das erste Mal davon erfuhr! –

1

Visual Studio hat eine praktische Option - Sie sollten einfach Ihre XML kopieren und einfügen und gehen Sie zum Menü Bearbeiten> Inhalte einfügen> Einfügen von XML als Klassen. Und Visual Studio generiert Klassen, mit denen Sie Ihr XML serialisieren/deserialisieren können. In diesem speziellen Fall wird es generieren:

[System.SerializableAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] 
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)] 
public partial class bla 
{ 
    private blaListOfListOfTest listOfListOfTestField; 

    public blaListOfListOfTest ListOfListOfTest 
    { 
     get { return this.listOfListOfTestField; } 
     set { this.listOfListOfTestField = value; } 
    } 
} 

[System.SerializableAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] 
public partial class blaListOfListOfTest 
{ 
    private blaListOfListOfTestListOfTest listOfTestField; 

    public blaListOfListOfTestListOfTest ListOfTest 
    { 
     get { return this.listOfTestField; } 
     set { this.listOfTestField = value; } 
    } 
} 

[System.SerializableAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] 
public partial class blaListOfListOfTestListOfTest 
{ 
    private object testField; 

    public object Test 
    { 
     get { return this.testField; } 
     set { this.testField = value; } 
    } 
} 

Sie können danach einige Anpassungen tun - zum Beispiel Entfernen Sie Typ-Qualifier oder ersetzen Sie Eigenschaften durch Auto-Eigenschaften (was mit Visual Studio-Erweiterungen möglich ist).Nach wenigen Tastendrücken:

[Serializable] 
[DesignerCategory("code")] 
[XmlType(AnonymousType = true)] 
[XmlRoot(Namespace = "", IsNullable = false)] 
public partial class bla 
{ 
    public blaListOfListOfTest ListOfListOfTest { get; set; } 
} 

[Serializable] 
[DesignerCategory("code")] 
[XmlType(AnonymousType = true)] 
public partial class blaListOfListOfTest 
{ 
    public blaListOfListOfTestListOfTest ListOfTest { get; set; } 
} 

[Serializable] 
[DesignerCategory("code")] 
[XmlType(AnonymousType = true)] 
public partial class blaListOfListOfTestListOfTest 
{ 
    public object Test { get; set; } 
} 

und Deserialisierung wird wie folgt aussehen:

var serializer = new XmlSerializer(typeof(bla)); 
var blaObj = serializer.Deserialize(new StringReader(xmlString)); 
Verwandte Themen