hcorion hcorion - 6 days ago 6
C# Question

C# Parse list of git commits using json.net

I've been browsing various websites and the JSON.net docs but I can't find an elegant way to do this.

The Problem



I have to parse a list of GitHub commits since a certain date.

The example json file I've been using for testing: example json file

The json is just a large (or empty) array. The problem is I don't need all of the data, I just need the sha of each commit.
However, if you look at each type in the array, there are multiple shas.

There is the base sha:

"sha": "fde139ae1d8fcf82bb145bbc99ed41763202e28f",


the tree sha:

"tree": {
"sha": "5d33d345f2df166bc4c56cc9307a61a5ee57d346",
"url": "https://api.github.com/repos/QuiZr/ProjectPorcupineLocalization/git/trees/5d33d345f2df166bc4c56cc9307a61a5ee57d346"
},


and the parent sha(s):

"parents": [
{
"sha": "8b9b43e813645c3a66911247b3dca916af937738",
"url": "https://api.github.com/repos/QuiZr/ProjectPorcupineLocalization/commits/8b9b43e813645c3a66911247b3dca916af937738",
"html_url": "https://github.com/QuiZr/ProjectPorcupineLocalization/commit/8b9b43e813645c3a66911247b3dca916af937738"
}
]


I only want the first sha. not the other shas.

Requirements




  • Needs to use JSON.net (not Ockokit)

  • Should be elegant

  • Needs to support the Unity game engine (i.e. C# version less than or equal to 2.0)

  • I really don't want to create a new object type just for this.


Answer

You can just use LINQ to JSON very easily in this case - parse the text as a JArray, then ask for the sha property of each object:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json.Linq;

class Test
{
    static void Main()
    {
        string json = File.ReadAllText("test.json");
        JArray array = JArray.Parse(json);
        List<string> hashes = array.Select(o => (string) o["sha"]).ToList();
        foreach (var hash in hashes)
        {
            Console.WriteLine(hash);
        }
    }
}

Note that this uses lambda expressions which are from C# 3, but that should be fine in Unity - it only supports the CLR v2, but the .NET 3.5 framework, I believe.

In future though, I wouldn't let concerns such as "It's only a small part of the codebase" put you off creating a type - if LINQ to JSON didn't exist, creating a model type for the commit and deserializing to that would be a perfectly good solution.

Comments