[英]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"
這些必須相同。 我假設這是問題的錯字。
您的查詢由以下幾部分組成-
您正在遍歷嵌套數組"friends.data[*].likes.data[*]"
所有like
數據對象,其中[*]
表示使用JSONPath語法的數組索引通配符。
您正在過濾id == "475723939105078"
那些對象
您似乎正在按重復方式對重復項進行分組和排序-盡管我不確定這一點,因為.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.