Querying JSON with JSONPath or SelectTokens? With

2019-05-29 01:30发布

问题:

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":"someone@awebsite.com",
                "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":"joe@awebsite.com",
                "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":"asitesame@awebsite.com",
                "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.

回答1:

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

        string json = GetJson();
        var obj = JObject.Parse(json);
        var testEmail = "someone@awebsite.com";

        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"]);