18

I've xml as following:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <data name="LogIn">Log In</data>
  <data name="Password">Password</data>
</root>

I success to do that without Linq, any one can help me to convert the following code to Linq:

using (XmlReader reader = XmlReader.Create(_xml))
{
    while (reader.Read())
    {
       if (reader.NodeType == XmlNodeType.Element && reader.LocalName == "data")
       {
          reader.MoveToAttribute("name");
          string key = reader.Value;
          reader.MoveToContent();
          string value = reader.ReadElementContentAsString();
          _dictionary.Add(key, value);
       }
    }
    reader.Close();
}
default
  • 11,485
  • 9
  • 66
  • 102
Ramzy Abourafeh
  • 1,195
  • 7
  • 17
  • 35

3 Answers3

21
var xdoc = XDocument.Load(path_to_xml);
_dictionary = xdoc.Descendants("data")
                  .ToDictionary(d => (string)d.Attribute("name"),
                                d => (string)d);
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
  • I got the following error: 'System.Collections.Generic.IEnumerable' does not contain a definition for 'ToDictionary' and no extension method 'ToDictionary' accepting a first argument of type 'System.Collections.Generic.IEnumerable' could be found (are you missing a using directive or an assembly reference?) – Ramzy Abourafeh Dec 19 '12 at 12:32
  • 6
    @RamzyAbourafeh Add `using System.Linq;` so you can use LINQ extension methods. – ken2k Dec 19 '12 at 12:34
  • @lazyberezovsky, what does `Descendants("data")` do ? – Habib Dec 19 '12 at 12:37
  • @Habib, it returns descendant elements for this document which have name `data` [msdn](http://msdn.microsoft.com/en-us/library/bb353813.aspx) - same as xpath `//data` – Sergey Berezovskiy Dec 19 '12 at 13:17
  • 1
    awesome! @Habib, maybe xdoc.Element("Root").Elements() is better suited for you? but does the same here. – efkah Dec 19 '12 at 13:27
  • 1
    @lazyberezovsky, +1 and thanks for the link, and thanks efkah – Habib Dec 19 '12 at 13:59
0
XDocument xdoc = XDocument.Load("test.XML");
var query = xdoc.Descendants("root")
                .Elements()
                .ToDictionary(r => r.Attribute("name").Value,
                             r => r.Value);

Remeber to include :

using System.Linq;
using System.Xml.Linq;
Bilal Hashmi
  • 1,465
  • 13
  • 12
0

This is an old question, but in case someone comes across a 'Typed' xml (e.g from a SharedPreference file of an android app), you can handle it as below: Here is a sample of such an xml I took from an Instagram app.

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<boolean name="pinnable_stickers" value="false" />
<string name="phone_number">+254711339900</string>
<int name="score" value="0" />
<string name="subscription_list">[]</string>
<long name="last_address_book_updated_timestamp" value="1499326818875" />
 //...other properties
</map>

Note the inconsistency in the value property. Some fields(e.g of type string) don't have it explicitly defined.

var elements = XElement.Load(filePath)
.Elements()
.ToList();
var dict = new Dictionary<string, string>();    
var _dict = elements.ToDictionary(key => key.Attribute("name").Value,
                        val => val.Attribute("value") != null ?
                        val.Attribute("value").Value : val.Value);
Felix Too
  • 11,614
  • 5
  • 24
  • 25