[英]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.