JSONPath可以快速提取json固定位置、范围的数据,而不需要创建单独的JSONObject对象。但如果每次处理的json数据格式会改变,则该方式不太适用。
JSONPATH | 描述 |
$ | 根对象,例如$.name |
[num] | 数组访问,其中num是数字,可以是负数。例如$[0].leader.departments[-1].name |
[num0,num1,num2...] | 数组多个元素访问,其中num是数字,可以是负数,返回数组中的多个元素。例如$[0,3,-2,5] |
[start:end] | 数组范围访问,其中start和end是开始小表和结束下标,可以是负数,返回数组中的多个元素。例如$[0:5] |
[start:end :step] | 数组范围访问,其中start和end是开始小表和结束下标,可以是负数;step是步长,返回数组中的多个元素。例如$[0:5:2] |
[?(key)] | 对象属性非空过滤,例如$.departs[?(name)] |
[key > 123] | 数值类型对象属性比较过滤,例如$.departs[id >= 123],比较操作符支持=,!=,>,>=,<,<= |
[key = '123'] | 字符串类型对象属性比较过滤,例如$.departs[name = '123'],比较操作符支持=,!=,>,>=,<,<= |
[key like 'aa%'] | 字符串类型like过滤, 例如$.departs[name like 'sz*'],通配符只支持% 支持not like |
[key rlike 'regexpr'] | 字符串类型正则匹配过滤, 例如departs[name rlike 'aa(.)*'], 正则语法为jdk的正则语法,支持not rlike |
[key in ('v0', 'v1')] | IN过滤, 支持字符串和数值类型 例如: $.departs[name in ('wenshao','Yako')] $.departs[id not in (101,102)] |
[key between 234 and 456] | BETWEEN过滤, 支持数值类型,支持not between 例如: $.departs[id between 101 and 201] $.departs[id not between 101 and 201] |
length() 或者 size() | 数组长度。例如$.values.size() 支持类型java.util.Map和java.util.Collection和数组 |
keySet() | 获取Map的keySet或者对象的非空属性名称。例如$.val.keySet() 支持类型:Map和普通对象 不支持:Collection和数组(返回null) |
. | 属性访问,例如$.name |
.. | deepScan属性访问,例如$..name |
* | 对象的所有属性,例如$.leader.* |
['key'] | 属性访问。例如$['name'] |
['key0','key1'] | 多个属性访问。例如$['id','name'] |
测试数据:
String jsonDemo = "{\"status\":200,\"msg\":\"成功\",\"data\":{\"name\":\"Smith\",\"age\":15,\"address\":\"青岛\"}}" ;
String jsonArrayDemo = "{\"status\":200,\"msg\":\"成功\",\"data\":[{\"name\":\"Lucy\",\"age\":10,\"address\":\"上海\"},{\"name\":\"Tom\",\"age\":12,\"address\":\"北京\"},{\"name\":\"Smith\",\"age\":15,\"address\":\"青岛\"},{\"name\":\"Jerry\",\"age\":21,\"address\":\"秦皇岛\"}]}";
样例一:判断JSONObject数据中指定路径key值是否符合预期
@Test
public void jsonFromJson() {
JSONObject jo = JSONObject.parseObject(jsonDemo);
String response = (String) JSONPath.eval(jo,"$.data.name");
if(response.equals("Lucy")) {
System.out.println("-----相同");
}else {
System.out.println("------不相同");
}
样例二:判断JSONObject数据中是否包含指定路径
@Test
public void jsonContainsKey() {
JSONObject jo = JSONObject.parseObject(jsonDemo);
//JSONPath.contains:检查json中是否包含指定路径的key
Assert.assertTrue(JSONPath.contains(jo,"$.data.name"));
}
样例三:判断JSONObject数据指定路径中是否包含预期的value
@Test
public void jsonContainValue() {
JSONObject jo = JSONObject.parseObject(jsonDemo);
//JSONPath.containsValue:检查json指定路径中是否包含预期的value
Assert.assertTrue(JSONPath.containsValue(jo,"$.data.name","Lucy"));
}
样例四:检查json指定路径中非空元素的个数是否符合预期
@Test
public void jsonValueSize() {
JSONObject jo = JSONObject.parseObject(jsonDemo);
//JSONPath.size:json指定路径中的非空元素个数
Assert.assertEquals(4,JSONPath.size(jo,"$.data"));
}
样例五:检查jsonAarry中多个元素的某个属性是否符合预期
@Test
public void jsonArrayCheck01() {
JSONObject jo = JSONObject.parseObject(jsonArrayDemo);
JSONArray ja = jo.getJSONArray("data");
//将JSONArray转换为ArrayList类型
ArrayList al = new ArrayList();
for(int i = 0; i < ja.size(); i++) {
al.add(ja.getJSONObject(i));
}
//读取ArrayList中,路径符合的所有值
List ln = (List)JSONPath.eval(al,"$.name");
//打印lizt中的所有值
for(String s : ln) {
System.out.println(s);
}
//打印list的内容
System.out.println(ln.toString());
//检查list中对应位置的值是否符合预期
Assert.assertEquals(ln.get(2),"Smith");
}
样例六:检查jsonArray中指定位置元素的属性是否正确
@Test
public void jsonArrayCheck02() {
JSONObject jo = JSONObject.parseObject(jsonArrayDemo);
JSONArray ja = jo.getJSONArray("data");
ArrayList al = new ArrayList();
for(int i = 0; i < ja.size(); i++) {
al.add(ja.getJSONObject(i));
}
//提取下标为1,2的元素
List lj1 = (List)JSONPath.eval(al,"[1,2]");
System.out.println(lj1.toString());
//提取最后一个元素
JSONObject lj2 = (JSONObject)JSONPath.eval(al,"[-1]");
System.out.println(lj2.toJSONString());
//提取下标为0的元素
JSONObject lj3 = (JSONObject)JSONPath.eval(al,"[0]");
System.out.println(lj3.toJSONString());
Assert.assertEquals(lj3.get("name"),"Lucy");
}
样例七:检查jsonArray中指定范围元素的属性是否正确
@Test
public void jsonArrayCheck03() {
JSONObject jo = JSONObject.parseObject(jsonArrayDemo);
JSONArray ja = jo.getJSONArray("data");
ArrayList al = new ArrayList();
for(int i = 0; i < ja.size(); i++) {
al.add(ja.getJSONObject(i));
}
//提取下标范围在[1:3]的元素子集
List lj1 = (List)JSONPath.eval(al,"[1:3]");
System.out.println(lj1.toString());
//提取第一个到倒数第二个范围内的元素子集
List lj2 = (List)JSONPath.eval(al,"[:-2]");
System.out.println(lj2.toString());
//检查lj2元素的个数是否为3
Assert.assertEquals(3,lj2.size());
}
样例八:提取jsonArray中符合过滤条件的元素,检查其属性是否正确
@Test
public void jsonArrayCheck04() {
JSONObject jo = JSONObject.parseObject(jsonArrayDemo);
JSONArray ja = jo.getJSONArray("data");
ArrayList al = new ArrayList();
for(int i = 0; i < ja.size(); i++) {
al.add(ja.getJSONObject(i));
}
//提取key是指定范围内的数据的下标
List lj1 = (List)JSONPath.eval(al,"[address in ('北京','上海')]");
System.out.println(lj1.toString());
//提取key是指定数据的下标
List lj2 = (List)JSONPath.eval(al,"[address ='北京']");
System.out.println(lj2.toString());
//提取key(数值类型)在指定范围内的下标
List lj3 = (List)JSONPath.eval(al,"[age between 10 and 15]");
System.out.println(lj3.toString());
}