参考:https://github.com/json-path/JsonPath
介绍
类似于XPath在xml文档中的定位,JsonPath表达式通常是用来路径检索或设置Json的。其表达式可以接受“dot–notation”和“bracket–notation”格式,例如$.store.book[0].title、$[‘store’][‘book’][0][‘title’]
操作符
符号 | 描述 |
---|---|
$ | 查询的根节点对象,用于表示一个json数据,可以是数组或对象. |
@ | 过滤器断言(filter predicate)处理的当前节点对象,类似于this. |
* | 通配符,可以表示一个名字或数字. |
.. | 可以理解为递归搜索 |
. |
表示一个子节点 |
[' |
表示一个或多个子节点 |
[ |
表示一个或多个数组下标 |
[start:end] | 数组片段,区间为[start,end),不包含end |
[?( |
过滤器表达式,表达式结果必须是boolean. |
过滤器操作符
过滤器是用于过滤数组的逻辑表达式,一个通常的表达式形如:[?(@.age > 18)],可以通过逻辑表达式&&或||组合多个过滤器表达式,例如[?(@.price < 10 && @.category == ‘fiction’)],字符串必须用单引号或双引号包围,例如[?(@.color == ‘blue’)] or [?(@.color == “blue”)]。
符号 | 描述 |
---|---|
== | left is equal to right (note that 1 is not equal to '1') |
!= | left is not equal to right |
< | left is less than right |
<= | left is less or equal to right |
> | left is greater than right |
>= | left is greater than or equal to right |
=~ | 判断是否符合正则表达式,例如[?(@.name =~ /foo.*?/i)] |
in | 所属符号,例如[?(@.size in [‘S’, ‘M’])] |
nin | 排除符号 |
subsetof | left is a subset of right [?(@.sizes subsetof ['S', 'M', 'L'])] |
anyof | left has an intersection with right [?(@.sizes anyof ['M', 'L'])] |
noneof | left has no intersection with right [?(@.sizes noneof ['M', 'L'])] |
size | size of left (array or string) should match right |
empty | 判空符号 |
JsonPath案例
json:
string json = @"{
""store"": {
""book"": [
{
""category"": ""reference"",
""author"": ""Nigel Rees"",
""title"": ""Sayings of the Century"",
""price"": 8.95
},
{
""category"": ""fiction"",
""author"": ""Evelyn Waugh"",
""title"": ""Sword of Honour"",
""price"": 12.99
},
{
""category"": ""fiction"",
""author"": ""Herman Melville"",
""title"": ""Moby Dick"",
""isbn"": ""0-553-21311-3"",
""price"": 8.99
},
{
""category"": ""fiction"",
""author"": ""J. R. R. Tolkien"",
""title"": ""The Lord of the Rings"",
""isbn"": ""0-395-19395-8"",
""price"": 22.99
}
],
""category"": ""store"",
""bicycle"": {
""color"": ""red"",
""price"": 19.95
}
},
""expensive"": 10
}
";
代码:
JObject jobj = JObject.Parse(json);
//递归搜索,搜索所有category
var tokens = jobj.SelectTokens("$..category");
int tokenCount = tokens.Count();//5
foreach (var token in tokens)
{
string value = token.ToString();
}
//reference、fiction、fiction、fiction、store
//查询所有书的category
tokens = jobj.SelectTokens("$.store.book[*].category");// or $.store..category
tokenCount = tokens.Count();//4
string tokenValue = tokens.ToList()[3].ToString();//fiction
//查询所有书的category、price
tokens = jobj.SelectTokens("$.store.book[*]['category','price']");// or $.store..category
tokenCount = tokens.Count();//8
tokenValue = tokens.ToList()[1].ToString();//8.95
//查询数组指定下标的节点
tokens = jobj.SelectTokens("$..book[0,1]").ToList();//前两个
tokens = jobj.SelectTokens("$..book[:2]").ToList();//前两个
tokens = jobj.SelectTokens("$..book[-2:]").ToList();//最后两个
tokens = jobj.SelectTokens("$..book[2:]").ToList();//第三个及之后的
//查询第一本书的所有叶子节点
tokens = jobj.SelectTokens("$.store.book[0].*");
tokenCount = tokens.Count();
string price = tokens.ToList()[3].ToString();//8.95
//查询第一本书的第一个叶子节点
//tokens = jobj.SelectTokens("$.store.book[0][0]");
//string category = tokens.First().ToString();//reference
//查询所有节点
tokens = jobj.SelectTokens("$..*");
tokenCount = tokens.Count();//30
//查询所有带isbn的书
tokens = jobj.SelectTokens("$..book[?(@.isbn)]").ToList();
tokenCount= tokens.Count();//2
//查询价格小于20的书
tokens = jobj.SelectTokens("$..book[?(@.price<20)]").ToList();
tokenCount = tokens.Count();//3
//查询价格小于expensive字段的书
tokens = jobj.SelectTokens("$..book[?(@.price<$.expensive)]").ToList();
tokenCount = tokens.Count();//2
//查询符合正则表达式的书
tokens = jobj.SelectTokens("$..book[?(@.author=~/^EVE/i)]").ToList();
tokenCount = tokens.Count();//1
以下案例与JsonPath无关
JSON:
var json = @"{
'course_editions': {
'2014/SL': [
{
'grades': {
'course_units_grades': {
'159715': {
'1': {
'value_symbol': '4','exam_session_number': 1,'exam_id': 198172,'value_description': {
'en': 'good'
}
}
}
},'course_grades': {}
}
},{
'grades': {
'course_units_grades': {
'159796': {
'2': {
'value_symbol': '5','exam_id': 198259,'value_description': {
'en': 'very good'
}
}
}
},'course_grades': {}
}
}
]
}
}";
案例1
获取所有course_units_grades节点下的第一个属性的名称
var jobj = JObject.Parse(json);
var coursesTokens = jobj.SelectTokens("course_editions.2014/SL[*].grades.course_units_grades")
.Select(o => o.First) //get the first child of `course_units_grades`
.Cast<JProperty>() //cast to JProperty
.Select(o => o.Name); //get the name of the property
foreach (string coursesToken in coursesTokens)
{
Console.WriteLine(coursesToken);
}
输出结果:
159715
159796
案例2
获取所有course_units_grades节点下的第一个属性值的第一个属性的名称
var jobj = JObject.Parse(json);
var coursesTokens = jobj.SelectTokens("course_editions.2014/SL[*].grades.course_units_grades")
.Select(o => o.First) //get the first child of `course_units_grades`
.Cast<JProperty>() //cast to JProperty
.Select(o => o.Value) //get the name of the property
.Select(o => o.First)
.Cast<JProperty>() //cast to JProperty
.Select(o => o.Name);
foreach (string coursesToken in coursesTokens)
{
Console.WriteLine(coursesToken);
}
输出结果:
1
2