繁体   English   中英

过滤来自Facebook的Json回复

[英]Filter Json response from Facebook

我正在尝试使用Json.Net的Json2Linq过滤Json响应,但是过滤过程中发生错误,提示“无法访问Newtonsoft.Json.Linq.JProperty上的子值”。 以下是我在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回应

{
"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"
            }]
        }
    }]
},

}

我在代码中的目标是过滤所有喜欢的朋友并返回ID:475723939105078的所有喜欢

首先是一个初步的问题。 您正在查询r["id"].Value<string>() == "475729939105078"但JSON中的ID值实际上是:

            "id": "475723939105078"

这些必须相同。 我假设这是问题的错字。

您的查询由以下几部分组成-

  1. 您正在遍历嵌套数组"friends.data[*].likes.data[*]"所有like数据对象,其中[*]表示使用JSONPath语法的数组索引通配符。

  2. 您正在过滤id == "475723939105078"那些对象

  3. 您似乎正在按重复方式对重复项进行分组和排序-尽管我不确定这一点,因为.Values<string>()旨在获取原始属性的值,而like.data对象实际上并不是原始属性,因此这部分查询失败。

另外,您正在混合使用LINQ和Lambda语法,这使事情更加混乱。 我建议选择一个并坚持使用。

可以使用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;

或使用lambda:

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

最后将SelectTokens()与JSONPath结合使用

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

为了进行比较,在您的查询中, "Cannot access child value on Newtonsoft.Json.Linq.JProperty." 错误是由于以下事实引起的,当您执行rss["friends"]["data"].First().SelectMany(l => l["likes"]) ,额外的First()获取第一个数组项,因此SelectMany()最终循环遍历like属性值 -这在令牌层次结构中太深了。

至于分组,您的JSON没有显示重复的like数据的示例,但是您始终可以使用JTokenEqualityComparer来识别和分组相同的JSON对象:

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

(这里我使用lambda语法来使用自定义IEqualityComparer<JToken> 。)

显示所有三个版本的样本小提琴

暂无
暂无

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

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