使用SelectTokens为具有更改结构的JSON对象查询JSON

时间:2017-07-27 10:16:01

标签: c# json json.net querying

这个问题与

中的以下内容非常相关

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

与上述问题类似,当JSON对象并不总是具有相同的简化数据结构时,如何进行Where查询,即

{
  "video": {
    "local_recording_device": {
      "codecs": null
    },
    "preferred_string": "___PREFERRED___",
    "streams": {
      "22855218": {
        "id": "22855218",
        "name": "AJA Camera"
      },
      "99176901": {
        "id": "99176901",
        "name": "PTZ Camera",
        "site": "someone",
        "email": "someone@awebsite.com",
        "codec": [
          "VP8",
          "HD1",
          "(720p)"
        ]
      },
      "3091494011": {
        "id": "3091494011",
        "name": "Logitech Webcam C930e",
        "site": "Joe Smith",
        "email": "joe@awebsite.com",
        "codec": [
          "VP8",
          "Medium",
          "(CIF)"
        ]
      },
      "3798287599": {
        "id": "3798287599",
        "name": "Drive Camera",
        "site": "ASiteName",
        "email": "asitesame@awebsite.com",
        "codec": [
          "HD1",
          "(720p)"
        ]
      }
    }
  }
}

如何让Where查询处理给定的编解码器,例如" VP8"

如果我这样查询它似乎无法使用我的应用程序:

string json = GetJson();
var obj = JObject.Parse(json);
var testcodec = "VP8";

var streamQuery = obj.SelectTokens("video.streams.*.codec")
                     .Where(s =>(string)s == testcodec);

但我的结果应该是这样的:

{  
  "video":{  
    "local_recording_device":{  
        "codecs":null
    },
    "preferred_string":"___PREFERRED___",
    "streams":{  
        "99176901":{  
            "id":"99176901",
            "name":"PTZ Camera",
            "site":"someone",
            "email":"someone@awebsite.com",
            "codec":[  
                "VP8"
            ]
        },
        "3091494011":{  
            "id":"3091494011",
            "name":"Logitech Webcam C930e",
            "site":"Joe Smith",
            "email":"joe@awebsite.com",
            "codec":[  
                "VP8"
            ]
        }
    }
  }
}

2 个答案:

答案 0 :(得分:1)

您的查询不起作用,因为它只询问编解码器数组,然后尝试将这些数组与字符串值进行比较。您需要一个询问流的查询,然后检查每个流的编解码器数组是否包含正确的字符串。

请尝试这样:

var streamQuery = obj.SelectTokens("video.streams.*")
                     .Where(t => t["codec"] != null &&
                                 t["codec"].Any(c => (string)c == testcodec));

然后你可以做这样的事情来从查询结果中获取数据:

foreach (var stream in streamQuery)
{
    Console.WriteLine("id: " + stream["id"]);
    Console.WriteLine("name: " + stream["name"]);
    Console.WriteLine("site: " + stream["site"]);
    Console.WriteLine("email: " + stream["email"]);
    Console.WriteLine("codecs: " + string.Join(", ", stream["codec"].Select(c => (string)c)));
    Console.WriteLine();
}

小提琴:https://dotnetfiddle.net/Ak8PMZ

答案 1 :(得分:0)

var streamQuery = obj.SelectTokens("$.video.streams.*.codec") .Where(x=>x.First.Value<string>()==testcodec);