简体   繁体   English

过滤来自Facebook的Json回复

[英]Filter Json response from Facebook

I'm trying to filter Json response using Json2Linq of Json.Net but error was occurred during filtering says "Cannot access child value on Newtonsoft.Json.Linq.JProperty." 我正在尝试使用Json.Net的Json2Linq过滤Json响应,但是过滤过程中发生错误,提示“无法访问Newtonsoft.Json.Linq.JProperty上的子值”。 below are my code on C# 以下是我在C#上的代码

   JObject rss = JObject.Parse(userJson);

        try
        {
            var FriendsLikes = from c in rss["friends"].First()["data"]
                               .SelectMany(l => l["likes"]
                               .Select(d => d["data"]).Where(r => r["id"].Value<string>() == "475729939105078")).Values<string>()
                               group c by c into g
                               orderby g.Count() descending
                               select new { FriendsLikes = g.Key };

            foreach (var item in FriendsLikes)
            {
                System.Diagnostics.Debug.WriteLine(item.FriendsLikes);
            }
        }
        catch (System.Exception e)
        {
            System.Diagnostics.Debug.WriteLine(e.Message);
        }

Facebook Json Response Facebook Json回应

{
"id": "999999999084775",
"name": "Alex Xx",
"first_name": "Alex",
"last_name": "Xx",
"gender": "male",
"link": "https://www.facebook.com/app_scoped_user_id/101999999999999/",
"locale": "en_US",
"email": "alexxxx@gmail.com",
"picture": {
    "data": {
        "url": "https://scontent.xx.fbcdn.net/v/t1.0-1/p50x50/18341660_101370733774524_7009999999999957463_n.jpg?oh=ec8675dfe23bbda00b6048647af62875&oe=59C0F7DF",
        "is_silhouette": false
    }
},
"friends": {
    "data": [{
        "id": "10213045626997937",
        "name": "Jayson Raga",
        "first_name": "Jayson",
        "last_name": "Ragasa",
        "gender": "male",
        "link": "https://www.facebook.com/app_scoped_user_id/10213045626997937/",
        "locale": "en_US",
        "picture": {
            "data": {
                "url": "https://scontent.xx.fbcdn.net/v/t1.0-1/p50x50/16114608_10211941851924250_4611916174586601978_n.jpg?oh=de4c0a7839e7e9e7ef6e29e18b885ef898&oe=59A99999",
                "is_silhouette": false
            }
        },
        "likes": {
            "data": [{
                "live_videos": {
                    "data": [{
                        "from": {
                            "name": "MyBeat",
                            "id": "475728822105078"
                        },
                        "permalink_url": "/MyBeat/videos/1283448691726531/",
                        "description": "@[141752355816253]:behind the decks live",
                        "creation_time": "2016-07-03T17:20:49+0000",
                        "id": "1261428671666530"
                    }]
                },
                "id": "475723939105078"
            }]
        }
    }]
},

} }

My goal in my code is to filter all my friends like and return all likes from ID:475723939105078 我在代码中的目标是过滤所有喜欢的朋友并返回ID:475723939105078的所有喜欢

First, a preliminary problem. 首先是一个初步的问题。 You are querying for r["id"].Value<string>() == "475729939105078" but the ID value in the JSON is actually: 您正在查询r["id"].Value<string>() == "475729939105078"但JSON中的ID值实际上是:

            "id": "475723939105078"

These need to be the same. 这些必须相同。 I'll assume this is a typo in the question. 我假设这是问题的错字。

Your query consists of several parts - 您的查询由以下几部分组成-

  1. You are looping through all like data objects inside nested arrays "friends.data[*].likes.data[*]" , where [*] indicates an array index wildcard using JSONPath syntax . 您正在遍历嵌套数组"friends.data[*].likes.data[*]"所有like数据对象,其中[*]表示使用JSONPath语法的数组索引通配符。

  2. You are filtering those objects with id == "475723939105078" 您正在过滤id == "475723939105078"那些对象

  3. You seem to be grouping duplicates and ordering by count -- though I'm not sure of this since .Values<string>() is intended to get the values of a primitive properties whereas the like.data objects are not, in fact primitives, so this part of the query fails. 您似乎正在按重复方式对重复项进行分组和排序-尽管我不确定这一点,因为.Values<string>()旨在获取原始属性的值,而like.data对象实际上并不是原始属性,因此这部分查询失败。

Also, you are mixing LINQ and Lambda syntax, which makes things more confusing. 另外,您正在混合使用LINQ和Lambda语法,这使事情更加混乱。 I'd suggest choosing one and sticking with it. 我建议选择一个并坚持使用。

The first two parts of the query can be accomplished using LINQ syntax as follows: 可以使用LINQ语法完成查询的前两个部分,如下所示:

        var id = "475723939105078";
        var friendLikesFiltered 
            = from f in rss["friends"]["data"]  // Loop through all entries f in friends.data
              from l in f["likes"]["data"]      // Then loop all entries in likes.data
              where (string)l["id"] == id       // where like.id == friendId
              select l;

Or using lambda: 或使用lambda:

        var id = "475723939105078";
        var friendLikesFiltered 
            = rss["friends"]["data"]
            .SelectMany(f => f["likes"]["data"])
            .Where(l => (string)l["id"] == id);

And finally using SelectTokens() with JSONPath : 最后将SelectTokens()与JSONPath结合使用

        var id = "475723939105078";
        var friendLikesFiltered
            = rss.SelectTokens("friends.data[*].likes.data[*]")
            .Where(l => (string)l["id"] == id);

For comparison, in your query, the "Cannot access child value on Newtonsoft.Json.Linq.JProperty." 为了进行比较,在您的查询中, "Cannot access child value on Newtonsoft.Json.Linq.JProperty." error is caused by the fact that, when you do rss["friends"]["data"].First().SelectMany(l => l["likes"]) the extra First() grabs the first array entry so the SelectMany() ends up looping through the like property values -- which is one level too deep in the token hierarchy. 错误是由于以下事实引起的,当您执行rss["friends"]["data"].First().SelectMany(l => l["likes"]) ,额外的First()获取第一个数组项,因此SelectMany()最终循环遍历like属性值 -这在令牌层次结构中太深了。

As for grouping, your JSON doesn't show an example of duplicated like data, but you can always JTokenEqualityComparer to to identify and group identical JSON objects: 至于分组,您的JSON没有显示重复的like数据的示例,但是您始终可以使用JTokenEqualityComparer来识别和分组相同的JSON对象:

        var friendLikes =
            friendLikesFiltered
            .GroupBy(l => l, new JTokenEqualityComparer())
            .OrderBy(g => g.Count())
            .Select(g => g.Key);

(Here I use lambda syntax in order to use the custom IEqualityComparer<JToken> .) (这里我使用lambda语法来使用自定义IEqualityComparer<JToken> 。)

Sample fiddle showing all three versions. 显示所有三个版本的样本小提琴

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM