Parsing Multidimensional JSON Array with Newtonsoft Json.NET

15,229

Instead of declaring a lot of classes, I would parse the json string as follows

JArray jArr = (JArray)JsonConvert.DeserializeObject(jsonstr);
foreach (var item in jArr)
{
    foreach(var subitem in item["TrailCoordinates"])
    {
        Console.WriteLine(subitem["Longitude"] + " " + subitem["Latitude"]);
    }
}

If monotouch supports dynamic you can also write

dynamic jArr2 = JsonConvert.DeserializeObject(jsonstr);
foreach (dynamic item in jArr2)
{
    foreach (var subitem in item.TrailCoordinates)
    {
        Console.WriteLine(subitem.Longitude + " " + subitem.Latitude);
    }
}

You can even use Linq

JArray jArr = (JArray)JsonConvert.DeserializeObject(jsonstr);
var coords = jArr
            .Select(x => x["TrailCoordinates"])
            .SelectMany(x=>x)
            .Where(x => x["TrailId"].ToString() == "40")
            .Select(x => new { Lat = double.Parse(x["Latitude"].ToString()), Lon=double.Parse(x["Longitude"].ToString()) })
            .ToArray();
Share:
15,229
k1komans
Author by

k1komans

Updated on June 05, 2022

Comments

  • k1komans
    k1komans about 2 years

    I have Json returning as the following:

    [{"CreatedBy":"GIS_DB","CreatedDate":"3/8/2012 10:44:00 AM","Id":39,"ModifiedBy":"","ModifiedDate":"","Name":"CF-39","StatusId":1,"TrailCoordinates":[{"CreatedBy":"GIS_DB","CreatedDate":"3/8/2012 10:44:00 AM","Id":1637,"Latitude":32.76004207,"Longitude":-97.34006853,"ModifiedBy":"","ModifiedDate":"","SortOrder":1,"TrailId":39},{"CreatedBy":"GIS_DB","CreatedDate":"3/8/2012 10:44:00 AM","Id":1638,"Latitude":32.76004333,"Longitude":-97.34012121,"ModifiedBy":"","ModifiedDate":"","SortOrder":2,"TrailId":39}]},{"CreatedBy":"GIS_DB","CreatedDate":"3/8/2012 10:44:00 AM","Id":40,"ModifiedBy":"","ModifiedDate":"","Name":"CF-40","StatusId":1,"TrailCoordinates":[{"CreatedBy":"GIS_DB","CreatedDate":"3/8/2012 10:44:00 AM","Id":3755,"Latitude":32.76034332,"Longitude":-97.3402069,"ModifiedBy":"","ModifiedDate":"","SortOrder":1,"TrailId":40},{"CreatedBy":"GIS_DB","CreatedDate":"3/8/2012 10:44:00 AM","Id":3756,"Latitude":32.76019181,"Longitude":-97.3402448,"ModifiedBy":"","ModifiedDate":"","SortOrder":2,"TrailId":40}]}]

    These are my classes...

    public class Trails
    {
        [MonoTouch.Foundation.Preserve]
        public Trails(){ TrailCoord = new List<trailcoords>();}
    
        [MonoTouch.Foundation.Preserve, JsonProperty("Name")]
        public string TrailName { get; set; }
    
        [MonoTouch.Foundation.Preserve, JsonProperty("StatusId")]
        public int StatusId { get; set; }
    
        [MonoTouch.Foundation.Preserve, JsonProperty("TrailCoordinates")]
        public List<trailcoords> TrailCoord { get; set; }
    //  public trailcoords 
    
    public Trails (string trailname, int statusid, List<trailcoords> trailcoord)
    {
        TrailName = trailname;
            StatusId = statusid;
            TrailCoord = trailcoord;
        }       
    }
    
    public class trailcoords
    {       
            [MonoTouch.Foundation.Preserve]
        public trailcoords(){}  
    [MonoTouch.Foundation.Preserve, JsonProperty("TrailId")]
        public string TrailId { get; set; }     
    
        [MonoTouch.Foundation.Preserve, JsonProperty("Latitude")]
        public double Latitude { get; set; }    
    [MonoTouch.Foundation.Preserve, JsonProperty("Longitude")]
        public double Longitude { get; set; }   
    
    public trailcoords (string trailid, double latitude, double longitude)
    {
        TrailId = trailid;
            Latitude = latitude;
            Longitude = longitude;
        }
    }
    
    List<Trails> Posts = JsonConvert.DeserializeObject<List<Trails>> ( json );
    

    So from here I am not sure how I would access the Latitude and Longitude items in my list. I can access things like TrailName no problem but not sure what i'm doing wrong with the items in the array within the array. I would like to add them so that I can plot them as lines in a structure similar to this that I made (hardcoded values):

    CLLocationCoordinate2D[] tmpTrail1 = new CLLocationCoordinate2D[]{
      new CLLocationCoordinate2D(32.751531, -97.361755),
      new CLLocationCoordinate2D(32.751451, -97.356625),
      new CLLocationCoordinate2D(32.751500, -97.332077),
    };
    
    CLLocationCoordinate2D[] tmpTrail2 = new CLLocationCoordinate2D[] {
      new CLLocationCoordinate2D(32.727353, -97.361139),
      new CLLocationCoordinate2D(32.747731, -97.359896),
      new CLLocationCoordinate2D(32.765735, -97.360360),
    };
    
    _trailOverlayPoints = new List<CLLocationCoordinate2D[]>();
    _trailOverlayPoints.Add(tmpTrail1);
    _trailOverlayPoints.Add(tmpTrail2);
    
  • k1komans
    k1komans about 12 years
    Thanks this is great! Using Linq would I be able to put in a "where" clause so that it only returns coordinates for a specific trail?