2013-12-25 4 views
1

Я не могу понять это сам. Мой XML-файл выглядит так:Linq to XML - разобрать узел в словаре

<section name="blah"> 
    <setting1 name="blah">blah</setting1> 
    <setting1 name="blah1">blah1</setting1> 
</section> 

<section name="foo"> 
    <setting2 name="sth">sth</setting2> 
    <setting2 name="sth1">lala</setting2> 
</section> 

И так далее.

То, что я хотел бы сделать, это разобрать каждую секцию в собственный индивидуальный словарь, как это:

Dictionary <string, string> foo; 
Dictionary <string, string> blah; 

XElement xelement = XElement.Load("test.xml"); 
IEnumerable<XElement> sections = xelement.Elements(); 
foreach (var section in sections) 
{ 
    switch (section.Attribute("name").Value) 
    { 
     case "foo": 
      foo = ... Something 
      break; 

     case "blah": 
      blah = ... Something 
      break; 
    } 
} 

И так далее.

После разбора:

foo["sth1"] <---- contains lala 
blah["blah1"] <---- contains blah1 

Как я могу добиться этого в Linq?

+1

Так вы * только * хотите элемент 'foo'? Как насчет 'блаха'? –

+0

Я хочу все элементы. Я редактировал код, чтобы было ясно. – szczurcio

+0

Кажется, что 'Dictionary >' будет лучшей ставкой тогда ... –

ответ

3

В то время как вы могли жестко закодировать имена, как переменные, я подозреваю, вы бы лучше с Dictionary<string, Dictionary<string, string>>:

var settings = element.Elements("section") 
    .ToDictionary(section => section.Attribute("name").Value, 
        section => section.Elements() 
         .ToDictionary(setting => setting.Attribute("name)".Value, 
            setting => setting.Value)); 

Console.WriteLine(settings["foo"]["sth1"]); // lala 

Это используется вложенный вызов ToDictionary, где вы указываете ключ и значение, заданное любому конкретному элементу. Значение каждого элемента внешнего словаря - это словарь, созданный из элементов внутри раздела.

+0

Это имеет смысл. Я хотел его жестко закодировать, потому что я не понял, что имена реальных тегов (как в ) не имеют значения (не спрашивайте меня почему). Спасибо :) – szczurcio

2
Dictionary <string, string> foo=new Dictionary<string,string>(); 
Dictionary <string, string> blah; 

XElement xelement = XElement.Load("D:\\x.xml"); 
IEnumerable<XElement> sections = xelement.Elements(); 
    foreach (var section in sections) 
    { 
      switch (section.Attribute("name").Value) 
      { 
       case "foo": 
        foreach (XElement element in section.Descendants().Where(p => p.HasElements == false)) 
     { 
      int keyInt = 0; 
      string keyName = element.Attribute("name").Value; 

      while (foo.ContainsKey(keyName)) 
       keyName = element.Attribute("name") + "_" + keyInt++; 

      foo.Add(keyName, element.Value); 
     } 
     foo.Dump(); 

        break; 

       case "blah": 

        break; 
      } 
    }