簡體   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