JSONPath Tutorial: Query JSON Like a Pro

Master JSONPath syntax with practical examples. Learn every operator, filter expression, and real-world query pattern to extract data from complex JSON structures.

Equipe JSONTechFebruary 1, 202511 min read

O que é JSONPath?

JSONPath é uma linguagem de consulta para JSON, semelhante ao que o XPath faz para XML. Ela permite entrar em uma estrutura JSON complexa e extrair exatamente os dados de que você precisa usando uma sintaxe de expressão concisa. Em vez de escrever laços e condicionais para percorrer objetos e arrays aninhados, você escreve uma única expressão de caminho como $.store.book[?(@.price < 10)].title e obtém todos os títulos de livros com preço abaixo de dez dólares.

Stefan Goessner apresentou o JSONPath em 2007, e desde então ele se tornou um padrão de fato em várias linguagens e ferramentas. Se você trabalha com APIs REST, arquivos de configuração ou qualquer dado JSON não trivial, o JSONPath vai economizar bastante tempo.

JSONPath vs. XPath: comparação rápida

Se você já conhece XPath, o JSONPath vai parecer familiar. A diferença principal é que o JSON tem um modelo de dados mais simples — objetos e arrays em vez de elementos, atributos e namespaces. Veja como os dois se comparam:

ConceitoXPathJSONPath
Raiz/$
Filho/child.child ou ['child']
Descida recursiva//..
Curinga**
Índice de array[1] (base 1)[0] (base 0)
Filtro[predicate][?(expression)]

Referência completa de operadores JSONPath

Toda expressão JSONPath parte da raiz $ e encadeia operadores para navegar mais fundo. Aqui estão todos os operadores que você precisa conhecer:

OperadorDescriçãoExemplo
$O objeto ou array raiz$ — o documento inteiro
.keyMembro filho pelo nome (notação com ponto)$.store.name
['key']Membro filho pelo nome (notação com colchetes)$['store']['name']
..Descida recursiva — busca em todos os descendentes$..price — todo campo "price"
*Curinga — todos os membros de um objeto ou array$.store.*
[n]Índice de array (base 0)$.items[0]
[start:end]Fatia de array (o fim é exclusivo)$.items[0:3] — os três primeiros itens
[start:end:step]Fatia de array com passo$.items[::2] — um sim, um não
[n,m]Vários índices de array$.items[0,2,4]
[?()]Expressão de filtro$.items[?(@.price > 10)]
@Nó atual (usado dentro de filtros)@.name == 'Alice'

JSON de exemplo para nossos exemplos

Usaremos este documento JSON ao longo do tutorial. Ele representa uma resposta pequena de API de uma livraria:

{
  "store": {
    "name": "TechBooks Online",
    "book": [
      { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95, "inStock": true },
      { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99, "inStock": false },
      { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99, "inStock": true },
      { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99, "inStock": true }
    ],
    "bicycle": { "color": "red", "price": 19.95 }
  }
}

Exemplos práticos de JSONPath

1. Obter o nome da loja

$.store.name

Resultado: "TechBooks Online"

2. Obter todos os títulos dos livros

$.store.book[*].title

Resultado: ["Sayings of the Century","Sword of Honour","Moby Dick","The Lord of the Rings"]

3. Obter o primeiro livro

$.store.book[0]

Resultado: o objeto inteiro do primeiro livro.

4. Obter o último livro

$.store.book[-1]

Índices negativos contam a partir do fim. -1 retorna o último elemento.

5. Fatia: os dois primeiros livros

$.store.book[0:2]

Retorna os livros nos índices 0 e 1. O índice final é exclusivo.

6. Obter todos os preços em todo o documento

$..price

Resultado: [8.95, 12.99, 8.99, 22.99, 19.95] O operador de descida recursiva .. encontra todo campo price, independentemente da profundidade.

7. Filtro: livros abaixo de US$ 10

$.store.book[?(@.price < 10)]

Retorna os dois livros com preço 8,95 e 8,99.

8. Filtro: livros que têm ISBN

$.store.book[?(@.isbn)]

Retorna apenas Moby Dick e The Lord of the Rings.

9. Filtro: livros de ficção em estoque

$.store.book[?(@.category == 'fiction' && @.inStock == true)]

Combine condições com && (e) e || (ou).

10. Vários índices

$.store.book[0,3]

Escolha elementos específicos.

11. Curinga em objeto

$.store.bicycle.*

Resultado: ["red", 19.95]

12. Obter autores de livros caros

$.store.book[?(@.price > 15)].author

Resultado: ["J. R. R. Tolkien"]

Experimente você mesmo: cole o JSON de exemplo acima e teste essas expressões no nosso JSONPath Tester.

Expressões de filtro em profundidade

As expressões de filtro são a parte mais poderosa do JSONPath. Elas ficam dentro de [?()] e avaliam uma condição booleana para cada elemento.

OperadorSignificadoExemplo
==Igual a@.status == 'active'
!=Diferente de@.role != 'admin'
>Maior que@.age > 18
>=Maior ou igual@.score >= 90
<Menor que@.price < 50
<=Menor ou igual@.quantity <= 0
=~Correspondência por regex (em algumas implementações)@.name =~ /^J.*/
&&E lógico@.price > 5 && @.price < 20
``

Um padrão comum é verificar se a propriedade existe. Escrever @.isbn sem operador de comparação retorna true se a propriedade existir e não for null.

Cenários do mundo real

Extrair todos os e-mails de uma resposta de API

$..email

O operador de descida recursiva encontra todo campo email, não importa onde esteja na hierarquia.

Encontrar produtos por faixa de preço

$.products[?(@.price >= 25 && @.price <= 100)]

Obter valores de configuração aninhados

$.config.database.connections[0].host

JSONPath em diferentes linguagens

JavaScript / Node.js

import { JSONPath } from "jsonpath-plus";
const data = { store: { book: [{ title: "Moby Dick", price: 8.99 }] } };
const titles = JSONPath({ path: "$.store.book[*].title", json: data });
console.log(titles); // ["Moby Dick"]

Python

from jsonpath_ng.ext import parse
data = {"store": {"book": [{"title": "Moby Dick", "price": 8.99}]}}
expr = parse("$.store.book[*].title")
matches = [match.value for match in expr.find(data)]
print(matches)  # ['Moby Dick']

Java

import com.jayway.jsonpath.JsonPath;
String json = "{\"store\":{\"book\":[{\"title\":\"Moby Dick\",\"price\":8.99}]}}";
List<String> titles = JsonPath.read(json, "$.store.book[*].title");
System.out.println(titles); // [Moby Dick]

Armadilhas e limitações

  • Sem especificação formal (até pouco tempo atrás). O IETF publicou o RFC 9535 em 2024 para padronizar a sintaxe, mas muitas bibliotecas ainda seguem a especificação original de Goessner.
  • Suporte a regex varia. O operador =~ não é suportado em todos os lugares.
  • Sem operações de escrita. JSONPath é somente leitura.
  • Desempenho em documentos enormes. A descida recursiva (..) percorre todos os nós.
  • Inconsistência no tipo de retorno. Algumas bibliotecas retornam um único valor; outras sempre retornam um array.
  • Caracteres especiais nas chaves. Use notação com colchetes para chaves com pontos ou espaços.

JSONPath vs. jq

  • JSONPath foi pensado para embutir em código de aplicação, com suporte de bibliotecas nas principais linguagens.
  • jq é uma linguagem completa de transformação de dados, mais poderosa, porém com curva de aprendizado mais íngreme.

Para consultar dados dentro de uma aplicação, JSONPath é a escolha pragmática. Para scripts de shell e pipelines de dados, o jq é difícil de superar.

Folha de referência rápida

O que você querJSONPath
Documento inteiro$
Propriedade específica$.user.name
Todos os itens do array$.items[*]
Primeiro item$.items[0]
Último item$.items[-1]
Intervalo de itens$.items[1:4]
Cada enésimo item$.items[::2]
Todos os campos "name" em qualquer lugar$..name
Filtrar por valor$.items[?(@.price < 10)]
Filtrar por existência$.items[?(@.discount)]
Várias condições$.items[?(@.qty > 0 && @.active)]

Experimente você mesmo: abra o JSONPath Tester para executar consultas nos seus próprios dados JSON em tempo real.

Ferramentas relacionadas