我正在尝试实现一个看似简单的 JSON 路径过滤器,但未能使其正常工作。想知道其他对 Json.NET 的 JSON 路径实现有更多经验的人是否对后续步骤有想法。
这种情况失败了,但我认为应该可行?
var jsonText = @"{
'event': {
'data': {
'intField': 1,
'stringField': 'hello'
}
}
}";
JObject json = JsonConvert.DeserializeObject<JObject>(jsonText);
string jsonPath = "$.event.data[?(@.intField == 1)]";
IList<JToken> output = json.SelectTokens(jsonPath).ToList();
// this check fails
Assert.IsTrue(output.ToList().Count > 0);
如果我通过在“数据”对象周围添加虚拟数组来处理 JSON 有效负载,那么我就可以让查询正常工作。但是,我宁愿不处理 JSON 有效负载。
var jsonText = @"{
'event': {
'data': [{
'intField': 1,
'stringField': 'hello'
}]
}
}";
JObject json = JsonConvert.DeserializeObject<JObject>(jsonText);
string jsonPath = "$.event.data[?(@.intField == 1)]";
IList<JToken> output = json.SelectTokens(jsonPath).ToList();
// now this works
Assert.IsTrue(output.ToList().Count > 0);
问题是 Json.NET 对 JsonPATH 过滤表达式运算符的实现[?()]
仅适用于过滤集合(数组)内的对象,不适用于其他对象内的对象。此限制报告于问题 #1256:JSONPath 脚本无法正确执行对象,Newtonsoft 回复道:
我对此不太确定。 JSONPath 中没有任何内容表明过滤器应应用于对象。
JamesNK评论于 2017 年 3 月 24 日
这种限制有时会出现,例如使用 Newtonsoft.Json.NET 搜索 JSON 根对象的正确 JsonPath 表达式是什么? or 如何过滤 JsonPath 中的非数组。您可能想要添加评论GitHub 上的问题如果您发现对对象内部的对象进行过滤很有用。
解决方法有时的工作是添加递归下降运算符..
在包含对象属性名称和过滤表达式运算符之间,如下所示:
string jsonPath = "$.event.data..[?(@.intField == 1)]";
而且,在您的具体情况下,修改后的查询现在可以运行并选择一个对象。演示小提琴here.
当然,这个修改后的查询也将匹配如下内容:
{
"event": {
"data": {
"extra_added_level_of_nesting": {
"intField": 1,
"stringField": "hello"
}
}
}
}
(小提琴#2here)因此该解决方法可能不足以满足您的需求。
该解决方法之所以成功,是因为 Json.NET 显然将递归下降运算符返回的结果视为一个集合,因此可以对其应用过滤表达式运算符。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)