tags:

views:

228

answers:

2

I've got a program that needs to convert two attributes of a particular tag to the key and value of an Dictionary<int,string>. The XML looks like this:

(fragment)

<startingPoint coordinates="1,1" player="1" />

and so far my LINQ looks something like this:

XNamespace ns = "http://the_namespace";
var startingpoints = from sp in xml.Elements(ns+"startingPoint")
                 from el in sp.Attributes()
                 select el.Value;

Which gets me a nice IEnumerable full of things like "1,1" and "1", but there should be a way to adapt something like this answer to do attributes instead of elements. Little help please? Thank you!

+3  A: 

I assume you want to store a mapping of all players and their respective starting point coordinates in the dictionary. The code for this would look like:

Dictionary<int, string> startingpoints = xml.Elements(ns + "startingPoint")
        .Select(sp => new { 
                              Player = (int)(sp.Attribute("player")), 
                              Coordinates = (string)(sp.Attribute("coordinates")) 
                          })
        .ToDictionary(sp => sp.Player, sp => sp.Coordinates);

Even better, you had a class for storing the coordinates, like:

class Coordinate{
    public int X { get; set; }
    public int Y { get; set; }

    public Coordinate(int x, int y){
        X = x;
        Y = y;
    }

    public static FromString(string coord){
        try
        {
            // Parse comma delimited integers
            int[] coords = coord.Split(',').Select(x => int.Parse(x.Trim())).ToArray();
            return new Coordinate(coords[0], coords[1]);
        }
        catch
        {
            // Some defined default value, if the format was incorrect
            return new Coordinate(0, 0);
        }
    }
}

Then you could parse the string into coordinates right away:

Dictionary<int, string> startingpoints = xml.Elements(ns + "startingPoint")
        .Select(sp => new { 
                              Player = (int)(sp.Attribute("player")), 
                              Coordinates = Coordinate.FromString((string)(sp.Attribute("coordinates"))) 
                          })
        .ToDictionary(sp => sp.Player, sp => sp.Coordinates);

You could then access the players coordinates like this:

Console.WriteLine(string.Format("Player 1: X = {0}, Y = {1}", 
                                startingpoints[1].X, 
                                startingpoints[1].Y));
Philip Daubmeier
A: 

I think you're looking to do something like this

string xml = @"<root>
                <startingPoint coordinates=""1,1"" player=""1"" />
                <startingPoint coordinates=""2,2"" player=""2"" />
               </root>";

XDocument document = XDocument.Parse(xml);

var query = (from startingPoint in document.Descendants("startingPoint")
             select new
             {
                 Key = (int)startingPoint.Attribute("player"),
                 Value = (string)startingPoint.Attribute("coordinates")
             }).ToDictionary(pair => pair.Key, pair => pair.Value);

foreach (KeyValuePair<int, string> pair in query)
{
    Console.WriteLine("{0}\t{1}", pair.Key, pair.Value);
}
Anthony Pegram