我正在寻找一种方法来选择JObject使用Json.NET 中的所有对象.简而言之,如果我有以下JSON:
{
"someCar" : {
"id" : "3",
"model" : "M7",
"engine" : "FI V8",
},
"name" : "carparkone",
"id" : "1",
"cars" : [
{
"id" : "1",
"model" : "s60",
"engine" : "i5",
},
{
"id" : "2",
"model" : "m3",
"engine" : "FI V6",
},
{
"id" : "3",
"model" : "M7",
"engine" : "FI V8",
}
]
}
Run Code Online (Sandbox Code Playgroud)
我会运行一些命令来获取其中所有对象的数组,即{}块中的任何对象.
理想情况下,我会找到的所有对象,其中someProp有some value,所以只有那些具有属性的对象engine具有的价值V6.
tl;博士问题:
当没有预定义架构时,您可以使用LINQ to JSON来解析和过滤 JSON 对象。
首先,将您的 JSON 解析为JObjectusing JToken.Parse()。然后,您可以使用JContainer.DescendantsAndSelf()以文档顺序遍历该根对象及其所有后代标记。(或者JContainer.Descendants()如果你想跳过根对象,请使用。)然后你可以过滤然后使用 using.OfType<JObject>()返回所有对象,无论是否嵌套:
var root = JObject.Parse(jsonString;
var allObjs = root.DescendantsAndSelf()
.OfType<JObject>()
.ToArray();
Run Code Online (Sandbox Code Playgroud)
要按某个值进行过滤,您可以添加一个附加Where()子句,如以下扩展方法所示:
public static partial class JTokenExtensions
{
public static JObject [] FilterObjects<T>(this JObject root, string someProp, T someValue)
{
var comparer = new JTokenEqualityComparer();
var someValueToken = JToken.FromObject(someValue);
var objs = root.DescendantsAndSelf()
.OfType<JObject>()
.Where(t => comparer.Equals(t[someProp], someValueToken))
.ToArray();
return objs;
}
}
Run Code Online (Sandbox Code Playgroud)
然后做:
var filteredObjs = root.FilterObjects(someProp, someValue);
Run Code Online (Sandbox Code Playgroud)
为了使其FilterObjects()完全通用,我将所需值序列化为 aJToken然后用于JTokenEqualityComparer将实际值与所需值进行比较。如果您知道所需的值是原始类型,则可以执行以下操作:
public static partial class JTokenExtensions
{
public static bool IsNull(this JToken token)
{
return token == null || token.Type == JTokenType.Null;
}
public static JObject[] FilterObjectsSimple<T>(this JObject root, string someProp, T someValue)
{
var comparer = EqualityComparer<T>.Default;
var objs = root.DescendantsAndSelf()
.OfType<JObject>()
.Where(t => { var v = t[someProp]; return v != null && (someValue == null ? v.IsNull() : comparer.Equals(v.ToObject<T>(), someValue)); })
.ToArray();
return objs;
}
}
Run Code Online (Sandbox Code Playgroud)
样品小提琴。
注意 - 您也可以考虑使用SelectTokens(),它支持JSONPath 查询语法,例如:
var someProp = "id";
var someValue = "3";
var filterString = string.Format(@"..*[?(@.{0} == '{1}')]", someProp, someValue);
var filteredObjs = root.SelectTokens(filterString).ToArray();
Run Code Online (Sandbox Code Playgroud)
但是,您的 JSON 包括直接嵌套在其他对象内部的对象,并且 Newtonsoft 的 JSONPath 实现找不到此类直接嵌套的对象,如JSONPath 脚本未正确执行对象 #1256 中所述。
| 归档时间: |
|
| 查看次数: |
1243 次 |
| 最近记录: |