Aller au contenu
jsonbeautifiers
Français

Filtrer du JSON

Extrayez uniquement ce dont vous avez besoin avec une expression de filtre JSONPath.

Document
Résultat

Rien de ce que vous collez ne quitte votre navigateur. La liste d’autorisation connect-src en fait une garantie du navigateur plutôt qu’une promesse. Vérifiez-le vous-même

Réduisez un gros document à la partie dont vous avez besoin, à l’aide d’une expression de filtre JSONPath. Le résultat revient sous forme de tableau JSON des valeurs correspondantes, prêt à copier.

Pour être clair sur ce que c’est : c’est du JSONPath, pas du jq. jq est un langage complet et un outil véritablement supérieur pour les transformations complexes. Ceci sert à sélectionner, ce que la plupart des filtrages sont en réalité.

Expressions de filtre

Toute la syntaxe au même endroit, puisque c’est la partie que l’on recherche à chaque fois.

$.items[?@.active]
Chaque élément dont la clé existe et est vraie. La seule existence est déjà un test valide.
$.items[?@.price < 10]
Comparaison numérique. L’ordre ne s’applique qu’entre deux nombres ou entre deux chaînes.
$.items[?@.type == 'book']
Comparaison de chaînes. Le littéral doit être entre guillemets, et c’est l’erreur la plus courante.
$.items[?@.price < 10 && @.stock > 0]
Conjonction avec && et disjonction avec ||, et regroupement avec des parenthèses.
$.items[?!@.archived]
Négation, qui signifie ici que la clé est absente ou fausse.
$.items[?length(@.tags) > 2]
Une extension de fonction. length() fonctionne sur les chaînes, les tableaux et les objets.
$.items[?match(@.sku, '[A-Z]{3}-[0-9]+')]
Une expression régulière ancrée à la valeur entière. Utilisez search() pour une correspondance partielle.
$..[?@.id == 42]
Un filtre appliqué à toutes les profondeurs, ce qui permet de trouver un enregistrement sans savoir où il se trouve.

Ce qu’il advient d’une clé absente

C’est le point sur lequel les implémentations pré-RFC divergeaient le plus, il vaut donc la peine de l’énoncer. Dans la RFC 9535, une requête qui ne sélectionne rien est « manquante », et une valeur manquante n’est égale qu’à une autre valeur manquante. Donc @.price < 10 est faux quand price est absent, plutôt que de lever une erreur ou de correspondre. Les deux membres d’une comparaison == doivent être manquants pour qu’elle soit vraie.

Conséquence pratique : pour tester l’absence, utilisez !@.price plutôt que @.price == null, car null est une valeur et l’absence n’en est pas une.

How to do this in code

Filtrer en code, là où jq est généralement la bonne réponse.

sh jq

Le troisième exemple est celui qui tranche : si vous avez besoin de regrouper ou d’agréger, prenez jq.

# Select, then reshape
jq '[.items[] | select(.price < 10) | {sku, price}]' data.json

# Filter at any depth
jq '[.. | objects | select(.id? == 42)]' data.json

# Group and aggregate, which JSONPath cannot do at all
jq 'group_by(.category) | map({category: .[0].category, n: length})' data.json
py Python
# A comprehension beats a query language for anything you
# can express directly.
cheap = [i for i in data['items'] if i['price'] < 10]

# JMESPath when the filter is configuration rather than code
import jmespath
cheap = jmespath.search("items[?price < `10`]", data)
js JavaScript
const cheap = data.items.filter((i) => i.price < 10);

// Deep search without a library
function findAll(node, test, out = []) {
  if (node && typeof node === 'object') {
    if (test(node)) out.push(node);
    for (const v of Object.values(node)) findAll(v, test, out);
  }
  return out;
}
const matches = findAll(data, (n) => n.id === 42);

Questions fréquentes

Pourquoi n’est-ce pas un bac à sable jq ?
Faire tourner du vrai jq dans un navigateur suppose de l’expédier compilé en WebAssembly, soit environ un mégaoctet. Sur un site dont l’argument est qu’il charge vite, c’est un mauvais échange pour un outil que la plupart des gens utilisent pour sélectionner et non pour transformer. Et appeler « bac à sable jq » un filtre JSONPath serait un mensonge, ce que ce site ne fait pas.
Puis-je filtrer et remodeler en même temps ?
Pas avec JSONPath : il sélectionne des nœuds, il n’en construit pas de nouveaux. Utilisez JMESPath, qui dispose des multiselect hashes, ou jq.
Comment trouver tous les objets ayant une clé donnée n’importe où dans le document ?
$..[?@.laClé] applique le filtre à toutes les profondeurs. Pour trouver un enregistrement précis, $..[?@.id == 42].