Access JSON item with variable key name

5.7k views Asked by At

The following is my JSON data which happens to be the format supplied by Wikidata, although greatly trimmed down for clarity.

{
"entities": {
    "Q200405": {
        "id": "Q200405",
        "type": "item",
        "claims": "Cheese"
        }
    }
}

I am attempting to access this data within c#. My problem is that the Q200405 is dynamic - it is basically the record number that I am retrieving. For example, another page might give me

{
"entities": {
    "Q123456": {
        "id": "Q123456",
        "type": "item",
        "claims": "Lemon"
        }
    }
}

My best attempt so far was using Json.NET (Newtonsoft) ;

json = "{\"entities\":{\"Q200405\" {\"id\":\"Q200405\",\"type\":\"item\",\"claims\":\"Cheese\"}}}";

var Query = JsonConvert.DeserializeObject<dynamic>(json);
string entities = Query.entities.ToString();

Query = JsonConvert.DeserializeObject<dynamic>(entities);
string entity = Query.Q200405.ToString();

Query = JsonConvert.DeserializeObject<dynamic>(entity);
string id = Query.id.ToString();
string claims = Query.claims.ToString();

This works, but obviously hardcoding Query.Q200405.ToString() is not the ideal solution! I probably should not be doing multiple Deserialize statements to drill down into the data either?

My question is what is the best way to read the above JSON format into a c# program?

2

There are 2 answers

7
Jon Skeet On BEST ANSWER

Well if you want to put the names into string variables, just use JObject:

string id = "Q200405"; // Or wherever you get that from
string text = "{\"entities...";
var json = JObject.Parse(text);

var claim = json["entities"][id];

string claims = (string) claim["claims"];
string type = (string) claim["type"];
// etc

Basically LINQ to JSON is really what you want here.

EDIT: If you don't know the ID beforehand, you can use:

var json = JObject.Parse(text);
var entities = (JObject) json["entities"];
var entity = entities.Properties().First();
var id = entity.Name;
var claim = (JObject) entity.Value;
string claims = (string) claim["claims"];
string type = (string) claim["type"];
Console.WriteLine(new { claims, type, id });
0
Tien Dinh On

This is how you can parse it

class Data
{
    public string id { get; set; }
    public string type { get; set; }
    public string claims { get; set; }
}

var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string,Data>>>(json);
Data data = obj["entities"].FirstOrDefault().Value;