Search code examples
c#.netjsonwikidata

How to iterate through a Wikidata JSON object?


I'm trying to iterate through a Wikidata JSON object and am successful up to a point. I'm parsing the following: http://www.wikidata.org/wiki/Special:EntityData/Q319.json

I'm iterating through with code like the following:

dynamic a = JsonConvert.DeserializeObject<dynamic>(wikidata_pageContents);
foreach (dynamic entity in a.entities) { 
    foreach (dynamic topLevelStructure in entity.Value) {
    ...

This works until I get to a 'claim' like the following.

{
    "mainsnak": {
        "snaktype": "value",
        "property": "P1036",
        "datavalue": {
            "value": "523.45",
            "type": "string"
        },
        "datatype": "string"
    },
    "type": "statement",
    "id": "Q319$5525e016-4210-bb2c-ce03-bd2dd52cca6c",
    "rank": "normal"
}

I'm using the following with the above JSON text in claim.Value however field_name is null.

foreach (dynamic claimField in claim.Value)
{
    string field_name = claimField.Name;

How can I dynamically iterate through the values in the above object? I'd rather iterate rather than try and establish an object structure and deserialise if possible.


Solution

  • Everything in your code above is correct, we just don't know how you get the claim, so I suppose the problem is there. This is very simple and work:

    dynamic a = JsonConvert.DeserializeObject<dynamic>(json);
    foreach (dynamic entity in a.entities)
    {
        foreach (dynamic topLevelStructure in entity.Value)
        {
            if (topLevelStructure.Name == "claims")
            {
                foreach (dynamic claimField in topLevelStructure.Value)
                {
                    var field_name = claimField.Name;
                    foreach (var p in claimField.Value)
                    {
                        var mainsnak = p.mainsnak;
                        var property = mainsnak.property.Value;
                        var datavalue = mainsnak.datavalue;
                        var value = datavalue.value.Value;
                        var type = datavalue.type.Value;
                    }
                }
            }
        }
    }
    

    Here is an another very simple way to get the all claims values by using Newtonsoft.Json.Linq:

    var claims = JObject.Parse(json)["entities"].First.First["claims"];
    foreach (var claim in claims.Children())
    {
        var mainsnak = claim.First.First["mainsnak"];
        var property = mainsnak["property"];
        var datavalue = mainsnak["datavalue"];
        var value = datavalue["value"];
        var type = datavalue["type"];
    }