Fastjson JSONPath


1. JSONPath introduction

fastjson versions after 1.2.0 support JSONPath. This is a very powerful feature that can be used as an Object Query Language (OQL) in the Java framework.

2. API

package com.alibaba.fastjson;

public class JSONPath {          
     //  求值,静态方法
     public static Object eval(Object rootObject, String path);

     // 计算Size,Map非空元素个数,对象非空元素个数,Collection的Size,数组的长度。其他无法求值返回-1
     public static int size(Object rootObject, String path);

     // 是否包含,path中是否存在对象
     public static boolean contains(Object rootObject, String path) { }

     // 是否包含,path中是否存在指定值,如果是集合或者数组,在集合中查找value是否存在
     public static boolean containsValue(Object rootObject, String path, Object value) { }

     // 修改制定路径的值,如果修改成功,返回true,否则返回false
     public static boolean set(Object rootObject, String path, Object value) {}

     // 在数组或者集合中添加元素
     public static boolean array_add(Object rootObject, String path, Object... values);
}

It is recommended to cache the JSONPath object, which can improve the performance of evaluation.

3. Support syntax

##[?(key)] Non-empty filtering of object attributes, for example $.departs[?(name)][key > 123]Comparison and filtering of numerical type object attributes, such as $.departs[id >= 123], the comparison operator supports =,!= ,>,>=,<,<=[key = '123']String type object attribute comparison filtering, such as $. departs[name = '123'], comparison operators support =,!=,>,>=,<,<=##[key like 'aa%' ]For example, $.departs[name like 'sz*'], wildcard only supports % [key rlike 'regexpr']For example, departments[name like 'aa(.)*'], [key in ('v0', 'v1')]For example: [key between 234 and 456]For example: length() or size()Supports type java.util.Map and java.util.Collection and array .##..deepScan attribute access, for example $..name* All properties of the object, such as $.leader.*['key'] property access. For example $['name']['key0','key1']Multiple attribute access. For example $['id','name']

The semantics of the following two ways of writing are the same:

$.store.book[0].title

and

$['store']['book'][0]['title']

4. Syntax example

JSONPATHDescription
$Root object, such as $.name
[num]Array access, where num is a number, Can be a negative number. For example, $[0].leader.departments[-1].name
[num0,num1,num2...]array multiple element access, where num is a number, which can be negative, and returns multiple elements in the array. For example, $[0,3,-2,5]
[start:end]array range access, where start and end are the beginning of the small table and the end of the next The index, which can be a negative number, returns multiple elements in the array. For example, $[0:5]
[start:end :step]array range access, where start and end are the starting small table and the ending subscript, you can is a negative number; step is the step size, returning multiple elements in the array. For example $[0:5:2]
String type like filtering, supports not like

String type regular matching filtering, The regular syntax is the regular syntax of jdk, supported not rlike

IN filtering, supports string and numerical types $.departs[name in ('wenshao','Yako')]
$.departs[id not in (101,102)]

BETWEEN filtering, supports numeric types, supports not between $.departs[id between 101 and 201]
$.departs[id not between 101 and 201]

Array length. For example $.values.size()
property access, for example $ .name
##$[1,2,3] 1, 2, 3 elements in the collection
JSONPathSemantics
$Root Object
$[-1]Last element
$[:-2]First to last second element
$[1:]All elements after the second one

public void test_entity() throws Exception {
   Entity entity = new Entity(123, new Object());

  Assert.assertSame(entity.getValue(), JSONPath.eval(entity, "$.value")); 
  Assert.assertTrue(JSONPath.contains(entity, "$.value"));
  Assert.assertTrue(JSONPath.containsValue(entity, "$.id", 123));
  Assert.assertTrue(JSONPath.containsValue(entity, "$.value", entity.getValue())); 
  Assert.assertEquals(2, JSONPath.size(entity, "$"));
  Assert.assertEquals(0, JSONPath.size(new Object[], "$")); 
}

public static class Entity {
   private Integer id;
   private String name;
   private Object value;

   public Entity() {}
   public Entity(Integer id, Object value) { this.id = id; this.value = value; }
   public Entity(Integer id, String name) { this.id = id; this.name = name; }
   public Entity(String name) { this.name = name; }

   public Integer getId() { return id; }
   public Object getValue() { return value; }        
   public String getName() { return name; }

   public void setId(Integer id) { this.id = id; }
   public void setName(String name) { this.name = name; }
   public void setValue(Object value) { this.value = value; }
}

List<Entity> entities = new ArrayList<Entity>();
entities.add(new Entity("wenshao"));
entities.add(new Entity("ljw2083"));

List<String> names = (List<String>)JSONPath.eval(entities, "$.name"); // 返回enties的所有名称
Assert.assertSame(entities.get(0).getName(), names.get(0));
Assert.assertSame(entities.get(1).getName(), names.get(1));

##5.3 Example 3

5.4 Example 4
List<Entity> entities = new ArrayList<Entity>();
entities.add(new Entity("wenshao"));
entities.add(new Entity("ljw2083"));
entities.add(new Entity("Yako"));

List<Entity> result = (List<Entity>)JSONPath.eval(entities, "[0:2]"); // 返回下标从0到2的元素
Assert.assertEquals(3, result.size());
Assert.assertSame(entities.get(0), result.get(0));
Assert.assertSame(entities.get(1), result.get(1));
Assert.assertSame(entities.get(2), result.get(1));

##5.5 Example 5

##5.6 Example 6

Determine whether to return the object based on the attribute value filtering conditions, modify the object, and add elements to the array attribute

5.7 Example 7

Map root = Collections.singletonMap("company", //
                                    Collections.singletonMap("departs", //
                                                             Arrays.asList( //
                                                                            Collections.singletonMap("id",
                                                                                                     1001), //
                                                                            Collections.singletonMap("id",
                                                                                                     1002), //
                                                                            Collections.singletonMap("id", 1003) //
                                                             ) //
                                    ));

List<Object> ids = (List<Object>) JSONPath.eval(root, "$..id");
assertEquals(3, ids.size());
assertEquals(1001, ids.get(0));
assertEquals(1002, ids.get(1));
assertEquals(1003, ids.get(2));