2016-05-18 19 views
0

Ich habe ein XML-Dokument:wie verschachtelte XML in LINQ laden

<preferences> 
    <section name="PREF_SECTION_NAME_1"> 
    <preference name="PREF_EXAMPLE_1" type="radio"> 
     <default value="true"></default> 
    </preference> 
    <preference name="PREF_EXAMPLE_2" type="radio"> 
     <default value="true"></default> 
    </preference> 
    <preference name="PREF_EXAMPLE_3" type="radio"> 
     <default value="true"></default> 
    </preference> 
    </section> 
    <section name="PREF_SECTION_NAME_2"> 
    <preference name="PREF_EXAMPLE_1" type="radio"> 
     <default value="true"></default> 
    </preference> 
    <preference name="PREF_EXAMPLE_2" type="radio"> 
     <default value="true"></default> 
    </preference> 
    <preference name="PREF_EXAMPLE_3" type="radio"> 
     <default value="true"></default> 
    </preference> 
    </section> 
</preferences> 

und ich vertrete diese in meinen Klassen:

public class Preference 
{ 
    public string Name { get; set; } 
    public bool Default { get; set; } 
} 

public class Section 
{ 
    public string Name { get; set; } 
    public List<Preference> Preference { get; set; } 
} 

public class Preferences 
{ 
    public List<Section> Section { get; set; } 
} 

und ich versuche, dies in meiner C# Methode zu laden :

var xDoc = XDocument.Load("XMLFile.xml"); 

var sections = xDoc.Root 
        .Elements("Preferences") 
        .Select(x => new List<Section> 
        { 
        //what do I put in here? 

        }) 
        .ToList(); 

Es scheint nichts offensichtlich zu sein, in das Bit zu legen // was stelle ich hier ein?

Ich habe viele Beispiele gesehen eine nicht verschachtelte Klasse auf diese Weise zu laden. Gibt es eine Möglichkeit, dies zu tun oder?

dank

+1

Das Muster, das ich vor, gefolgt habe, ist eine Factory-Methode in jeder Klasse haben eine 'XElement' akzeptieren - und das andere nennen können, so dass die' statische Abschnitt FromXElement (XElement) 'Methode nennen würde' Preference.FromXElement' für Beispiel ... sehen, ob das genug ist, Sie –

+0

@JonSkeet dank Einstieg werde ich in aussehen, dass –

+0

@JonSkeet ich bei einem Ihrer Antworten hier auf der Suche war, die eine gute Art und Weise schien dies zu tun http://stackoverflow.com/questions/566167/Abfrage-an-XDocument-for-Elemente-by-Name-at-any-Tiefe –

Antwort

2

Dies ist, was Sie wollen:

var preferences = 
    new Preferences() 
    { 
     Section = xDoc.Root.Elements("section").Select(x => 
      new Section() 
      { 
       Name = x.Attribute("name").Value, 
       Preference = x.Elements("preference").Select(y => 
        new Preference() 
        { 
         Name = y.Attribute("name").Value, 
         Default = (bool)y.Element("default").Attribute("value"), 
        }).ToList(), 
      }).ToList() 
    }; 

Das gibt:

preferences

1

Sie könnten dies tun wollen.

var sections = xDoc.Root 
        .Descendants("section") 
        .Select(x => new Section 
        { 
        Name = x.Attribute("name").Value, 
        Preference = x.Elements("preference") 
            .Select(y=> new Preference 
              { 
               Name = (string)y.Attribute("name"), 
               Default = (bool)y.Element("default").Attribute("value") 
              }) 
            .ToList() 
        }) 
       .ToList() 

So jetzt Ihre (root) Preferences Instanz kann mit unten erstellt werden.

var preferences = new Preferences {Section = sections }; 

prüfen diese Demo

+0

dies ist eine gute Antwort. Das vorherige Poster funktioniert jedoch auch. Ich versuche zu sehen, welches besser ist, aber ich glaube nicht, dass ich qualifiziert bin, dieses Urteil zu fällen! –

+0

Wenn ich nur 2 akzeptierte Antworten vergeben kann! Ich muss mit dem anderen Plakat gehen, da sie 1. waren und es hat funktioniert. Vielen Dank für Ihre Hilfe, Präsentation/Demo :) –

+0

ist das in Ordnung, keine Sorgen :-) –

1
 var xDoc = XDocument.Load("sample1.xml"); 
     var sections = xDoc.Root.Descendants("section") 
          .Select(x => new Section 
          { 
           Name = x.Attribute("name").Value, 
           Preference = GetPreference(x) 
          }).ToList(); 

    private static List<Preference> GetPreference(XElement x) 
    { 
     return x.Descendants("preference").Select(y => new Preference 
              { 
               Name = y.Attribute("name").Value, 
               Default = ConvertToBool(y.Descendants("default").FirstOrDefault().Attribute("value").Value) 
              }).ToList(); 
    } 

    private static bool ConvertToBool(string trueOrFalse) 
    { 
     return trueOrFalse == "true" ? true : false; 
    } 

Dies sollte helfen.