Querying JSON with JSONPath or SelectTokens? With JSON.NET in C#

stopmotion24 picture stopmotion24 · Jun 12, 2015 · Viewed 18.1k times · Source

I am trying to use the Newtonsoft.Json.Net in c#. The following is part of JSON file that I need to retrieve data out of:

{
    "video":{
        "local_recording_device":{
            "codecs":null
        },
        "preferred_string":"___PREFERRED___",
        "streams":{
            "99176901":{
                "id":"99176901",
                "name":"PTZ Camera",
                "site":"someone",
                "email":"[email protected]",
                "codec":"VP8 HD1 (720p)",
                "local":true,
                "screen":false,
                "fit_to_window":true,
                "stay_on_top":false,
                "layout":0,
                "native_width":1280,
                "native_height":720,
                "window_width":456,
                "window_height":254,
                "preferred":false,
                "local_recording":false,
                "device_id":"MJPEG Camera",
                "normalized_device_id":"MJPEGCamera",
                "shared_window_id":"MJPEG Camera",
                "enable":true,
                "big_location":"2",
                "x":347,
                "y":737,
                "window_id":"197302",
                "camera_id":null
            },
            "3091494011":{
                "id":"3091494011",
                "name":"Logitech Webcam C930e",
                "site":"Joe Smith",
                "email":"[email protected]",
                "codec":"VP8 Medium (CIF)",
                "local":false,
                "screen":false,
                "fit_to_window":true,
                "stay_on_top":false,
                "layout":0,
                "native_width":352,
                "native_height":288,
                "window_width":864,
                "window_height":702,
                "preferred":true,
                "local_recording":false,
                "enable":true,
                "big_location":"1",
                "x":204,
                "y":0,
                "window_id":"197296",
                "camera_id":null
            },
            "3798287599":{
                "id":"3798287599",
                "name":"Drive Camera",
                "site":"ASiteName",
                "email":"[email protected]",
                "codec":"VP8 HD1 (720p)",
                "local":true,
                "screen":false,
                "fit_to_window":true,
                "stay_on_top":false,
                "layout":0,
                "native_width":1280,
                "native_height":720,
                "window_width":456,
                "window_height":254,
                "preferred":true,
                "local_recording":false,
                "device_id":"Logitech Webcam C930e",
                "normalized_device_id":"LogitechWebcamC930e",
                "shared_window_id":"Logitech Webcam C930e",
                "enable":true,
                "big_location":"3",
                "x":814,
                "y":737,
                "window_id":"262822",
                "camera_id":null
            }
        }
    }
}

So, inside the JSON data is: "video", "streams" inside streams can be x amount of different streams (stream id's). The streams in "streams" (the long numbers) can change at anytime. In my example here there are three. I need to search through all streams in "streams" and see if any of them has a "email" that matches a particular email address. Each of the streams has a "email". If a email matches my supplied email address I need to check that streams "enable" to see if it's true or false.

Any help is appreciated in leading me in the right direction. I have not worked with a JSON data before.

Answer

dbc picture dbc · Jun 18, 2015

You can use LINQ to JSON and SelectTokens to do the required query:

        string json = GetJson();
        var obj = JObject.Parse(json);
        var testEmail = "[email protected]";

        var streamQuery = obj.SelectTokens("video.streams.*").Where(s => (string)s["email"] == testEmail);
        var firstEnabled = streamQuery.Select(s => (bool?)s["enable"]).FirstOrDefault();

The query returns a nullable bool that is true or false if the first stream for the desired email is enabled, or null if there is no stream for that email address.

Note that this returns the enabled state of the first stream matching the given email address. If you want to know if any are enabled, do:

        var anyEnabled = streamQuery.Any(s => (bool)s["enable"]);