[英]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 - 您的查询由以下几部分组成-
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语法的数组索引通配符。
You are filtering those objects with id == "475723939105078"
您正在过滤id == "475723939105078"
那些对象
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>
。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.