Skip to content
Voltar ao blog
Tutoriais

Guia de sintaxe JSONPath: consultar e filtrar JSON com exemplos

Aprenda a sintaxe JSONPath com exemplos prontos para copiar: raiz, descida recursiva, curingas, fatias e filtros. Teste cada consulta direto no seu navegador.

11 min de leitura

Guia de sintaxe JSONPath: consultar e filtrar JSON com exemplos

JSONPath é uma linguagem de consulta para JSON, assim como XPath é uma linguagem de consulta para XML. Você escreve uma expressão de caminho e o avaliador retorna todos os valores que correspondem. Para pegar todos os nomes de autores de um documento de livraria, você escreve $.store.book[*].author — e recebe de volta a lista de autores, sem precisar de código de travessia.

Este guia percorre cada seletor da sintaxe JSONPath com exemplos prontos para copiar que você pode executar à medida que lê. Vale esclarecer uma coisa logo no início: existem dois dialetos. O dialeto Goessner de 2007 é o clássico de fato, e a RFC 9535 é o padrão formal da IETF publicado em fevereiro de 2024. Eles concordam nos caminhos comuns e divergem nos casos de borda, então este guia sinaliza as diferenças à medida que elas surgem. Você pode testar cada expressão abaixo no JSONPath Tester e alternar entre os dois motores para comparar.

Aqui está a tabela de referência rápida dos seletores para começar. O restante do artigo expande cada linha com um exemplo prático contra um único documento JSON compartilhado.

SeletorSignificadoExemplo
$Raiz do documento$
@Elemento atual (em filtros)[?(@.price < 10)]
.name / ['name']Membro filho$.store.book
..Descida recursiva$..author
*Todos os elementos / membros$.store.book[*]
[0]Índice de array$.store.book[0]
[start:end:step]Fatia de array (semiaberta)$.store.book[0:2]
[a,b]União de nomes / índices$.store.book[0,2]
[?()]Expressão de filtro$.store.book[?(@.price < 10)]
length() count() match() search() value()Funções RFC 9535 (apenas em filtros)[?length(@.title) > 15]

O que é JSONPath?

JSONPath é uma linguagem de consulta declarativa para selecionar nós de um documento JSON. Em vez de escrever um laço que percorre objetos e arrays, você descreve a localização que deseja com um caminho, e o avaliador retorna os valores correspondentes. O modelo mental é o mesmo que o XPath oferece para XML: um caminho feito de seletores que avançam pela estrutura.

Ele aparece em todo lugar onde desenvolvedores tocam em JSON. Você o usa para extrair um campo de uma resposta de API, para validar um valor em um teste de integração, para endereçar campos em configurações de pipeline para Kubernetes, AWS Step Functions e Azure Logic Apps, e para extrair dados de JSON grande ou irregular sem escrever lógica de travessia à mão.

Uma nota rápida sobre o histórico, porque ela explica a divisão de dialetos. Stefan Goessner propôs o JSONPath em 2007. Ele se espalhou rápido e virou um padrão de fato, mas nunca foi formalmente especificado — então as implementações foram se afastando nos detalhes. A IETF fechou essa lacuna em fevereiro de 2024 com a RFC 9535, a primeira especificação formal de JSONPath. Os dois dialetos seguem vivos hoje, e é por isso que a mesma expressão pode se comportar de maneira diferente dependendo de qual biblioteca a executa.

Antes de começar a consultar, vale a pena ler a estrutura. Formate uma entrada bagunçada com o JSON Formatter para que o aninhamento fique visível.

O documento de exemplo

Todos os exemplos abaixo rodam contra o clássico JSON de livraria do Goessner. Cole isto uma vez e reutilize:

{
  "store": {
    "book": [
      { "title": "Sayings of the Century", "author": "Nigel Rees", "price": 8.95 },
      { "title": "Sword of Honour", "author": "Evelyn Waugh", "price": 12.99 },
      { "title": "Moby Dick", "author": "Herman Melville", "price": 8.99 },
      { "title": "The Lord of the Rings", "author": "J. R. R. Tolkien", "price": 22.99 }
    ],
    "bicycle": { "color": "red", "price": 19.95 }
  }
}

Quatro livros com título, autor e preço, mais uma bicicleta. Tenha isto em mente: os preços são 8.95, 12.99, 8.99 e 22.99, e é isso que determina os resultados dos filtros mais adiante.

Raiz, filho e descida recursiva ($ . ..)

Toda expressão começa na raiz, escrita $. A partir daí, você entra nos filhos com um ponto ou com a notação de colchetes — as duas são equivalentes:

$.store.book          → the book array
$['store']['book']    → identical result

A notação de colchetes é o que você precisa quando uma chave tem espaços, pontos ou outros caracteres especiais: $['first name'] funciona onde $.first name não funcionaria.

O operador .. é a descida recursiva. Ele busca em todos os níveis do documento, não apenas nos filhos diretos, e reúne tudo o que corresponde ao seletor seguinte em qualquer profundidade:

$..author
→ ["Nigel Rees", "Evelyn Waugh", "Herman Melville", "J. R. R. Tolkien"]

Quando usar .. em vez de um caminho completo

A descida recursiva é conveniente, mas pouco precisa. $..price corresponde a todo preço em qualquer lugar da árvore — incluindo store.bicycle.price, que talvez você não quisesse. Quando você conhece o formato, escreva o caminho por extenso para que a consulta permaneça precisa:

$..price                  → [8.95, 12.99, 8.99, 22.99, 19.95]  (includes the bicycle)
$.store.book[*].price     → [8.95, 12.99, 8.99, 22.99]         (only books)

Reserve .. para estruturas genuinamente irregulares ou desconhecidas. A troca é conveniência contra controle: quanto mais você conhece seus dados, mais deve preferir um caminho explícito.

Curingas, índices e fatias de array (* [0] [start:end:step])

O curinga * seleciona todos os elementos de um array ou todos os membros de um objeto:

$.store.book[*].title
→ ["Sayings of the Century", "Sword of Honour", "Moby Dick", "The Lord of the Rings"]

Os índices de array começam em zero, e índices negativos contam a partir do fim:

$.store.book[0].title     → ["Sayings of the Century"]
$.store.book[-1].title    → ["The Lord of the Rings"]

As fatias usam a mesma convenção semiaberta [start:end:step] de Python e JavaScript: start é incluído, end é excluído.

$.store.book[0:2].title   → ["Sayings of the Century", "Sword of Honour"]

Isso retorna dois livros, não três — índice 0 e índice 1, parando antes do índice 2. O limite final exclusivo é o bug de JSONPath mais comum de todos, então vale a pena gravar na memória:

[0:2]   → first TWO elements (indices 0, 1)   ← correct
[0:3]   → first THREE elements (indices 0, 1, 2)

Omita um limite para ir até a borda, e adicione um passo para pegar cada N-ésimo elemento:

$.store.book[2:].title    → ["Moby Dick", "The Lord of the Rings"]
$.store.book[:3].title    → first three titles
$.store.book[::2].title   → ["Sayings of the Century", "Moby Dick"]  (every other)

Expressões de filtro [?()]

Um filtro [?()] mantém apenas os elementos para os quais um predicado é verdadeiro, e dentro do filtro, @ se refere ao elemento atual sendo testado.

Para selecionar livros mais baratos que 10:

$.store.book[?(@.price < 10)].title
→ ["Sayings of the Century", "Moby Dick"]

Contra os preços da livraria (8.95, 12.99, 8.99, 22.99), dois livros se qualificam. Veja como montar predicados de filtro passo a passo:

  1. Compare com um literal. Use ==, !=, <, <=, >, >= — por exemplo @.price > 10.
  2. Corresponda uma string. Literais de string usam aspas simples: @.author == 'Nigel Rees'.
  3. Teste a existência. Uma referência de membro isolada seleciona os elementos que a possuem: [?(@.isbn)] mantém apenas livros com um isbn.
  4. Combine condições. Junte predicados com && e ||: [?(@.price < 10 && @.author == 'Herman Melville')].

O erro mais frequente em filtros é o escopo de @. Dentro do predicado, o elemento atual é @, não $. Escrever $.price aponta de volta para a raiz do documento, não para o livro em teste:

$.store.book[?($.price < 10)]   → wrong scope, matches nothing useful
$.store.book[?(@.price < 10)]   → correct: each book's own price

RFC 9535 vs Clássico nos filtros

Os dois dialetos se separam no espaçamento e nas aspas. O Clássico é tolerante — [?(@.price<10)] sem espaços é analisado sem problema. A RFC 9535 segue sua gramática à risca e é mais rígida quanto à forma de escrever o filtro. Se um filtro que funcionava em outro lugar falha, verifique o espaçamento e o motor. Mantenha os filtros limpos (operadores com espaços, strings entre aspas simples) e eles serão avaliados da mesma maneira, independentemente de qual biblioteca acabar executando.

Seletores de união — selecionar várias chaves de uma vez ([a,b])

Um seletor de união lista vários nomes ou índices dentro de um colchete e reúne todos eles:

$.store.book[0]['title','author']
→ ["Sayings of the Century", "Nigel Rees"]

As uniões também funcionam com índices, e você pode combiná-las com outros seletores para uma projeção fixa:

$.store.book[0,2].title          → ["Sayings of the Century", "Moby Dick"]
$.store.book[*]['title','price']  → title and price of every book

As uniões são a ferramenta certa quando você quer alguns campos específicos em vez de um objeto inteiro ou uma varredura com curinga.

Funções RFC 9535: length, count, match, search, value

A RFC 9535 define cinco extensões de função padrão. A regra que pega quase todo mundo de surpresa, e que muitos guias erram, é esta:

Essas funções só podem ser chamadas dentro de um filtro [?...], nunca como um segmento de caminho isolado.

Escrever $.store.book.length() não é RFC 9535 válido, e a gramática do padrão o rejeita. Essa forma de chamada como segmento é uma extensão do jsonpath-plus, não parte da especificação. Para filtrar por tamanho, você chama a função dentro do predicado:

$.store.book[?length(@.title) > 15]
→ [
    { "title": "Sayings of the Century", "author": "Nigel Rees", "price": 8.95 },
    { "title": "The Lord of the Rings", "author": "J. R. R. Tolkien", "price": 22.99 }
  ]

Os dois títulos selecionados têm mais de 15 caracteres; “Moby Dick” (9) e “Sword of Honour” (15, não acima de 15) ficam de fora.

Veja o que cada função faz dentro de um filtro:

  • length() — comprimento de uma string, array ou objeto: [?length(@.title) > 15]
  • count() — número de nós em uma lista de nós: [?(count(@.authors) > 1)]
  • match() — teste de regex sobre a string inteira (padrão I-Regexp): [?match(@.author, 'J.*')]
  • search() — teste de regex de subcadeia: [?search(@.title, 'the')]
  • value() — converte uma lista de nós de um único nó em seu valor para comparação

Todas as cinco são um recurso da RFC 9535. O dialeto Clássico (Goessner) não as implementa, então, se uma expressão baseada em função falha, confirme que você está chamando-a dentro de um filtro e que seu motor está configurado para RFC 9535.

RFC 9535 vs Clássico Goessner — por que a mesma expressão difere

Quando uma expressão JSONPath retorna resultados diferentes em duas ferramentas, o dialeto costuma ser o motivo. Veja como os dois se comparam:

AspectoClássico Goessner (2007)RFC 9535 (2024)
PadronizaçãoDe fato, nunca formalizadoPrimeira especificação formal da IETF
Espaçamento/aspas em filtrosTolerante ([?(@.price<10)] OK)Rígido, segue a gramática à risca
Comparação de membro ausenteDefinida pela implementaçãoBem definida, não lança erro
Funções padrãoNão fazem parte do dialetolength count match search value
Caminhos normalizadosSem forma canônicaCanônica, em colchetes com aspas simples
Ordenação de uniãoVaria por bibliotecaEspecificada

Conselho prático: se o seu sistema downstream anuncia conformidade com a RFC 9535, escreva e valide contra o motor padrão. Se você está mantendo uma expressão copiada do jsonpath.com, do jsonpath-plus ou de um serviço baseado em Jayway, use o Clássico para que os resultados se reproduzam. O JSONPath Tester roda os dois motores atrás de um único interruptor, então você cola uma expressão uma vez e vê como cada dialeto a trata lado a lado. Essa comparação direta costuma ser a maneira mais rápida de localizar onde os dois divergem.

JSONPath vs XPath vs jq — qual usar

Esses três costumam ser confundidos, então aqui está a versão curta:

  • JSONPath é uma consulta de caminho declarativa para JSON. Funciona melhor embutido em configurações e validações de teste, onde você quer nomear uma localização sem escrever código.
  • XPath é o equivalente no mundo XML. O JSONPath emprestou parte de sua notação (*, .., []), e é por isso que a analogia se sustenta, mas as linguagens não são intercambiáveis e os conjuntos de funções diferem.
  • jq é um processador JSON de linha de comando. Ele vai muito além da seleção por caminho — transformação, agregação, reformatação — e vive no seu pipeline de shell.

A decisão geralmente é clara. Para uma validação embutida ou um campo de configuração de pipeline, escolha o JSONPath. Para transformação e manipulação de dados pela shell, escolha o jq — o Guia do jq cobre esse fluxo em profundidade. E quando a pergunta é se um payload está em conformidade com um formato esperado, em vez de onde um campo está, valide-o com o JSON Schema Validator e seu guia completo de validação.

7 erros comuns de JSONPath

  1. Esquecer a raiz $. store.book é rejeitado pela maioria dos motores; toda expressão começa em $.
  2. Fatia com erro de um. [0:2] são dois elementos, não três — o limite final é exclusivo.
  3. Dialeto errado. Rodar uma expressão Clássica sob RFC 9535 (ou vice-versa) pode dar erro de análise ou corresponder a nós diferentes. Troque o motor para combinar.
  4. Função como segmento isolado. $.store.book.length() é RFC 9535 inválido; chame length() dentro de um filtro.
  5. Esquecer o @ em um filtro. [?($.price < 10)] aponta para a raiz; use [?(@.price < 10)].
  6. Aspas erradas no colchete. $[store] é um erro; coloque a chave entre aspas: $['store'].
  7. Supor que .. para no primeiro nível. A descida recursiva corresponde em todas as profundidades, não apenas nos filhos diretos.

Teste JSONPath online, em privacidade

A forma mais rápida de aprender a sintaxe JSONPath é executá-la. O JSONPath Tester avalia cada expressão deste guia ao vivo: motores duplos RFC 9535 e Clássico, visões de resultado Values / Paths / Both, caminhos normalizados para depuração e execução 100% no navegador — sem upload, sem cadastro e sem eval, o que o torna seguro para payloads proprietários. Monte um caminho aqui, confirme que ele seleciona exatamente os nós que você quer e, então, cole a expressão validada direto no seu código, testes ou pipeline.

Para o restante do fluxo de trabalho com JSON, transforme uma resposta de exemplo em interfaces tipadas com o JSON to TypeScript, ou compare dois documentos campo a campo com o JSON Diff.

Perguntas frequentes

Para que serve o JSONPath?

O JSONPath consulta JSON sem código imperativo. Os desenvolvedores o usam para extrair campos de respostas de API, validar valores em testes de integração e endereçar campos em configurações para Kubernetes, AWS Step Functions e Azure Logic Apps. Ele brilha ao extrair dados de estruturas grandes ou irregulares, onde escrever uma travessia à mão seria tedioso.

Qual é a diferença entre RFC 9535 e JSONPath clássico?

O Clássico é o dialeto de fato de Stefan Goessner, de 2007 — amplamente implementado, mas nunca formalmente especificado, e por isso as bibliotecas divergiram. A RFC 9535 é a especificação formal da IETF de fevereiro de 2024: ela define uma gramática precisa, caminhos normalizados para os resultados e cinco funções padrão. Os dois diferem nas bordas em filtros, uniões e comparação de membro ausente.

Como funcionam as expressões de filtro do JSONPath?

Um filtro [?()] mantém apenas os elementos cujo predicado é verdadeiro, e @ é o elemento atual. Por exemplo, $.store.book[?(@.price < 10)] seleciona livros com preço abaixo de 10. Você pode combinar condições com && e ||, testar se um membro existe e comparar com literais de string ou número.

Posso usar length() como $.store.book.length()?

Não. Na RFC 9535, length() e as outras quatro funções só podem ser chamadas dentro de um filtro, como $.store.book[?length(@.title) > 15]. A forma de segmento isolado $.store.book.length() é uma extensão do jsonpath-plus, não JSONPath padrão, e a gramática da RFC 9535 a rejeita.

JSONPath é o mesmo que XPath?

Não, mas a ideia é parecida. O XPath consulta XML; o JSONPath consulta JSON; os dois localizam nós com seletores de caminho. O JSONPath emprestou de propósito parte da notação do XPath — *, .. e [] — o que torna a analogia útil, mas a sintaxe, a semântica e os conjuntos de funções são diferentes e não intercambiáveis.

O que a descida recursiva (..) faz no JSONPath?

O operador .. busca em todos os níveis do documento, não apenas nos filhos diretos. $..author reúne todo membro author onde quer que ele apareça, em qualquer profundidade de aninhamento. É a forma mais rápida de extrair um único campo de uma estrutura profundamente aninhada ou irregular, mas pode corresponder a muito mais nós do que você espera — restrinja-a quando puder.

Tags: jsonpath json query-language rfc-9535 filter-expression developer-tools

Artigos relacionados

Ver todos os artigos