Fastjson JSONPath


1. Introduction à JSONPath

Les versions fastjson après 1.2.0 prennent en charge JSONPath. Il s'agit d'une fonctionnalité très puissante qui peut être utilisée comme langage de requête d'objet (OQL) dans le framework Java.

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);
}

Il est recommandé de mettre en cache les objets JSONPath, ce qui peut améliorer les performances d'évaluation.

3. Prise en charge de la syntaxe

par exemple $.departs[nom comme 'sz*'], le caractère générique ne prend en charge que %support pas commePar exemple, départements[nom comme 'aa(.)*'], La syntaxe régulière est la syntaxe régulière de jdk, ne prenant pas en charge rlikePar exemple : $.departs[nom dans ('wenshao','Yako')] $.departs[id not in (101,102)] Par exemple : $.departs[id entre 101 et 201]$.departs[id pas entre 101 et 201] prend en charge les types java.util.Map et java.util.Collection et l'accès aux propriétés array .
JSONPATHDescription
$objet racine, tel que $.name
[num] numéro Accès de groupe, où num est un nombre, peut être un nombre négatif. Par exemple, $[0].leader.departments[-1].name
[num0,num1,num2...]Plusieurs éléments du tableau sont accessibles, où num est un nombre, qui peut être un nombre négatif et renvoie le nombre dans le tableau Plusieurs éléments. Par exemple, $[0,3,-2,5]
[start:end]accès à la plage du tableau, où début et fin sont la petite table de début et l'indice de fin, qui peuvent être des nombres négatifs et renvoyer plusieurs nombres dans l'élément du tableau. Par exemple, $[0:5]
[start:end :step]array range access, où start et end sont la petite table de début et l'indice de fin, qui peut être des nombres négatifs, step est l'étape ; size et renvoie les éléments multiples. Par exemple $[0:5:2]
[?(key)]Filtrage non nul de l'attribut d'objet, par exemple $.departs[?(name)]
[key > valeur numérique Filtrage de comparaison d'attributs d'objet de type, par exemple $.departs[id >= 123], les opérateurs de comparaison prennent en charge =,!=,>,>=,<,<=
[key = '123' [ clé comme 'aa%']Type de chaîne comme le filtrage,
[clé rlike ' regexpr']

Filtrage de correspondance régulière de type chaîne,
[entrez ('v0 ', 'v1') ]

Filtrage IN, prend en charge les types chaîne et numériques

[clé entre 234 et 456]

FILTRE ENTRE, prend en charge les types numériques, ne prend pas en charge entre

length() Ou size()

longueur du tableau. Par exemple, $.values.size()

, telles que la propriété $.name
..deepScan accès, par exemple, $..name
*Toutes les propriétés de l'objet, telles que $.leader.*
['key']property access. Par exemple $['name']
['key0','key1']Accès à plusieurs attributs. Par exemple $['id','name']

La sémantique des deux façons d'écrire suivantes est la même :

$.store.book[0].title

et

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

4 Exemple de syntaxe

JSONPathSémantique
$. Objet racine
$[ -1]Dernier élément
$[:-2]1er au 2ème au dernier
$[1:]Tous les éléments après le 2ème
$[ 1,2,3]1,2,3 éléments dans l'ensemble

5. Exemple d'API

5.1 Exemple 1

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; }
}

5.2 Exemple 2

Lire un attribut de plusieurs éléments dans l'ensemble

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 Exemple 3

Renvoyer plusieurs éléments dans l'ensemble

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, "[1,2]"); // 返回下标为1和2的元素
Assert.assertEquals(2, result.size());
Assert.assertSame(entities.get(1), result.get(0));
Assert.assertSame(entities.get(2), result.get(1));

5.4 Exemple 4

Renvoyer un sous-ensemble de l'ensemble par plage

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 Exemple 5

Renvoyer un sous-ensemble de la collection via le filtrage conditionnel

List<Entity> entities = new ArrayList<Entity>();
entities.add(new Entity(1001, "ljw2083"));
entities.add(new Entity(1002, "wenshao"));
entities.add(new Entity(1003, "yakolee"));
entities.add(new Entity(1004, null));

List<Object> result = (List<Object>) JSONPath.eval(entities, "[id in (1001)]");
Assert.assertEquals(1, result.size());
Assert.assertSame(entities.get(0), result.get(0));

5.6 Exemple 6

Déterminer s'il faut renvoyer l'objet en fonction sur la condition de filtrage des valeurs d'attribut , modifier l'objet, Ajouter des éléments aux attributs du tableau

Entity entity = new Entity(1001, "ljw2083");
Assert.assertSame(entity , JSONPath.eval(entity, "[id = 1001]"));
Assert.assertNull(JSONPath.eval(entity, "[id = 1002]"));

JSONPath.set(entity, "id", 123456); //将id字段修改为123456
Assert.assertEquals(123456, entity.getId().intValue());

JSONPath.set(entity, "value", new int[0]); //将value字段赋值为长度为0的数组
JSONPath.arrayAdd(entity, "value", 1, 2, 3); //将value字段的数组添加元素1,2,3

5.7 Exemple 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));