How to get XML into a dictionary in c#

I have the following XML:

<Axis>
    <Collections>
        <Collection>
            <Client>
                <Name>Client 1</Name> 
                <Value>345</Value> 
            </Client>
        </Collection>
        <Collection>
            <Client>
                <Name>Client 1</Name> 
                <Value>4532</Value> 
            </Client>
        </Collection>
        <Collection>
            <Client>
                <Name>Client 1</Name> 
                <Value>235</Value> 
            </Client>
        </Collection>
        <Collection>
            <Client>
                <Name>Client 1</Name> 
                <Value>8756</Value> 
            </Client>
        </Collection>
        <Collection>
            <Client>
                <Name>Client 1</Name> 
                <Value>76</Value> 
            </Client>
        </Collection>
    </Collections>
    <Collections>
        <Collection>
            <Client>
                <Name>Client 2</Name> 
                <Value>56</Value> 
            </Client>
        </Collection>
        <Collection>
            <Client>
                <Name>Client 2</Name> 
                <Value>43</Value> 
            </Client>
        </Collection>
        <Collection>
            <Client>
                <Name>Client 2</Name> 
                <Value>34</Value> 
            </Client>
        </Collection>
        <Collection>
            <Client>
                <Name>Client 3</Name> 
                <Value>42</Value> 
            </Client>
        </Collection>
        <Collection>
            <Client>
                <Name>Client 3</Name> 
                <Value>23</Value> 
            </Client>
        </Collection>
    </Collections>
</Axis>

and I would like to store some of this in a dictionary Dictionary<string, List<string>> where the key is the name element and the value is a list of the Value elements.

I have mucked around with a bit of LINQ, but I have not been able to work out the dictionary part.

I have been able to get one element into a list:

myDoc.XPathSelectElements("//Axis/Collections/Collection/Client/Value")
     .Select(v => v.Value)
     .ToList();
Jon Skeet
people
quotationmark

I would suggest:

  • Not using XPath to select elements, but using the Elements() method (etc) instead
  • Using a lookup instead of a Dictionary<string, List<string>>, via ToLookup. A lookup is like a dictionary with multiple values per key, but slightly simpler to handle (as it returns an empty sequence if you ask for a missing key) and much easier to construct.

So the code would look something like:

var lookup = doc.Root
                .Elements("Collections")
                .Elements("Collection")
                .Elements("Client")
                .ToLookup(x => (string) x.Element("Name"),
                          x => (string) x.Element("Value"));

You can then do things like:

foreach (var value in lookup["Client 1"])
{
    ...
}

An alternative to all the Elements() calls would be to use Descendants(), e.g.

var lookup = doc.Descendants("Client")
                .ToLookup(x => (string) x.Element("Name"),
                          x => (string) x.Element("Value"));

people

See more on this question at Stackoverflow