我正在尝试使用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
答案 0 :(得分:1)
首先,一个初步的问题。您正在查询like
,但JSON中的ID值实际上是:
"friends.data[*].likes.data[*]"
这些必须相同。我认为这是问题中的拼写错误。
您的查询包含几个部分 -
您正在遍历嵌套数组[*]
内的所有id == "475723939105078"
数据对象,其中like.data
表示使用JSONPath syntax的数组索引通配符。
您正在使用 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;
您似乎正在按重要次数对重复项进行分组 - 虽然我不确定这一点,因为.Values<string>()
旨在获取原始属性的值,而 var id = "475723939105078";
var friendLikesFiltered
= rss["friends"]["data"]
.SelectMany(f => f["likes"]["data"])
.Where(l => (string)l["id"] == id);
实际上,对象不是原语,因此查询的这一部分失败。
此外,您正在混合使用LINQ和Lambda语法,这会让事情变得更加混乱。我建议选择一个并坚持下去。
查询的前两部分可以使用LINQ语法完成,如下所示:
var id = "475723939105078";
var friendLikesFiltered
= rss.SelectTokens("friends.data[*].likes.data[*]")
.Where(l => (string)l["id"] == id);
或者使用lambda:
"Cannot access child value on Newtonsoft.Json.Linq.JProperty."
最后使用SelectTokens()
with JSONPath:
rss["friends"]["data"].First().SelectMany(l => l["likes"])
为了进行比较,在您的查询中,First()
错误是由以下事实引起的:当您执行SelectMany()
时,额外like
抓取第一个数组条目,以便{{1}最终循环遍历 like
属性值 - 这是令牌层次结构中的一个级别。
至于分组,您的JSON没有显示重复 var friendLikes =
friendLikesFiltered
.GroupBy(l => l, new JTokenEqualityComparer())
.OrderBy(g => g.Count())
.Select(g => g.Key);
数据的示例,但您始终可以JTokenEqualityComparer
来识别和分组相同的JSON对象:
{{1}}
(这里我使用lambda语法来使用自定义IEqualityComparer<JToken>
。)
示例fiddle显示所有三个版本。