FreeToGenerate.com

Roda um motor RFC 9535 de verdade: passa nos 703 testes de conformidade. Nada é enviado.

Experimente

Qualquer um que seja válido. A consulta roda enquanto você digita.

Resultados

2 nós

[
  "Sayings of the Century",
  "Moby Dick"
]

Caminhos normalizados

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

Cada resultado tem também um caminho normalizado: a única forma inequívoca de escrever uma consulta que selecione exatamente aquele nó. A especificação define essa forma para que duas implementações consigam concordar sobre o que encontraram, e ela sempre usa notação de colchetes com aspas simples.

Ordem dos resultados

Fixa. Qualquer implementação conforme devolve estes nós nesta ordem.

Só duas coisas deixam a ordem em aberto, e a especificação nomeia as duas. Uma é selecionar membros de um objeto, porque objetos JSON não têm ordem; já os arrays sempre mantêm a deles. A outra é um segmento com mais de um seletor, que ainda produz duplicatas: uma consulta como [0,0] seleciona o mesmo nó duas vezes, e a especificação declara explicitamente não conforme a implementação que o devolve uma vez só.

Medido contra a suíte oficial de testes

testes aprovados
703/703
deles, consultas inválidas
247
aceitam várias ordens
9

A RFC 9535 acompanha uma suíte de conformidade, então o quanto uma implementação funciona é um número, não uma alegação. Este motor passa nos 703. Um terço desse corpus são consultas que precisam ser REJEITADAS, e é aí que um analisador permissivo falha: aceitar uma consulta malformada conta como falha mesmo quando não havia resposta sensata possível.

Por que o padrão importa aqui

O JSONPath circulou por duas décadas como um post de blog sem especificação. Cada implementação inventou suas respostas e elas discordavam em consultas comuns, e é por isso que a mesma expressão podia devolver coisas diferentes em linguagens diferentes. A RFC 9535 chegou em fevereiro de 2024 e resolve isso: a expressão implementation-defined não aparece nem uma vez.

A regra que a maioria das implementações antigas erra é a de tipos. Uma comparação só pode envolver um literal, uma consulta singular — uma que no máximo selecione um nó — ou uma função que devolva um valor. Então uma consulta como $[?@.* == 1] é erro de sintaxe, e não uma comparação que silenciosamente não devolve nada. E um caminho que não seleciona nada produz um valor especial chamado Nothing, igual apenas a si mesmo: dois caminhos ausentes comparam iguais, enquanto um caminho ausente não é nem menor nem igual a um número.

Construído conforme a RFC 9535, com as expressões regulares da RFC 9485. Nada é enviado: a consulta roda nesta aba.

Também disponível em: English · Español · Français · العربية

Testador de JSONPath

Avalie uma consulta JSONPath no seu JSON e veja os nós correspondentes, seus caminhos normalizados e se a ordem do resultado é fixada pelo padrão.

O que é JSONPath

JSONPath é uma linguagem de consulta para JSON, assim como XPath é para XML. Uma expressão como $.store.book[?@.price < 10].title entra num documento e extrai as partes que você quer: todos os livros abaixo de dez, e só o título. Ela aparece no Kubernetes e no kubectl, em configurações de CI, em pipelines de log, em API gateways e em muitíssimas bibliotecas que precisavam de um jeito de dizer a qual parte de um payload se referiam.

Durante quase toda a sua vida ela não teve especificação. Começou como um post de blog em 2007, todo mundo implementou a partir daquela descrição, e as implementações discordavam em silêncio: a mesma consulta podia devolver coisas diferentes, em outra ordem, dependendo da linguagem em que você a rodasse. Não havia documento algum a que recorrer quando duas delas divergiam.

A RFC 9535 mudou isso em fevereiro de 2024. Este testador roda uma implementação real desse padrão: cole uma consulta e um documento e você recebe os nós correspondentes, o caminho normalizado de cada um, e uma afirmação sobre se a ordem que você está vendo é garantida.

Como usar

  1. Escreva uma consulta. Parta dos exemplos, se quiser: um filtra por preço, outro junta todos os preços do documento, e dois mostram o que acontece quando a ordem não é fixada. Os resultados atualizam enquanto você digita.
  2. Cole o seu JSON. Qualquer documento válido. Se ele não for analisável, a ferramenta diz isso em vez de fingir que a consulta falhou.
  3. Leia os caminhos e a nota sobre a ordem. Cada resultado carrega o seu caminho normalizado, a única forma inequívoca de endereçar aquele nó. Abaixo, a ferramenta informa se qualquer implementação conforme devolveria esses nós nessa ordem, ou se outra é livre para divergir.

O que o padrão resolve, e as duas coisas que não

A boa notícia é o quanto a RFC 9535 fixa. A expressão implementation-defined não aparece nem uma vez. A ordem do percurso descendente, a semântica das fatias com passo negativo, o que uma comparação faz quando um lado não seleciona nada: tudo especificado, tudo testável.

Existem exatamente dois lugares em que a ordem do resultado fica em aberto, e a especificação nomeia os dois em vez de deixar você descobrir. O primeiro é selecionar membros de um objeto: objetos JSON não têm ordem, então um curinga sobre um deles pode vir em qualquer sentido. Arrays não são afetados — a ordem deles é sempre preservada — que é justamente a metade que as pessoas costumam achar que está em risco.

O segundo é um segmento com mais de um seletor, como [0,0] ou [*,*]. Isso produz cada nó correspondente uma vez por seletor — duplicado de verdade, não deduplicado — e o entrelaçamento não é fixo. Este vale conhecer porque a especificação faz questão de dizer que implementações que devolvem esse nó só uma vez não são conformes. Se você contava com uma biblioteca colapsando duplicatas, esse comportamento não é o padrão.

A regra que a maioria das implementações antigas erra é a de tipos. Uma comparação só pode envolver um literal, uma consulta singular — uma que no máximo selecione um nó — ou uma função que devolva um valor. Então $[?@.* == 1] é erro de sintaxe, e não uma comparação que silenciosamente não casa com nada. E um caminho que não seleciona nada produz um valor especial chamado Nothing, igual apenas a si mesmo: dois caminhos ausentes comparam iguais, enquanto um caminho ausente não é nem menor nem maior que um número. Da própria derivação dos operadores na especificação segue que dois caminhos ausentes também comparam menor-ou-igual.

Como este motor foi conferido, e o que isso não prova

A RFC 9535 acompanha uma suíte oficial de conformidade, o que transforma em número o quanto uma implementação funciona. São 703 testes e este motor passa em todos. Esse número é verificado na compilação, então não pode apodrecer em silêncio.

Um terço desse corpus — 247 testes — são consultas que precisam ser rejeitadas. É aí que um analisador permissivo falha, e é uma parte considerável do trabalho: o padrão é rígido quanto a espaços em branco, quanto a onde uma consulta não singular pode aparecer, e quanto a quais escapes são válidos dentro de um nome entre aspas. Aceitar uma consulta malformada conta como falha mesmo sem haver resposta sensata possível.

Uma pontuação perfeita não prova correção, e esta compilação ilustra bem isso. A especificação define apenas dois operadores de comparação e deriva o resto, de modo que a menor-ou-igual a b significa a menor que b ou a igual a b. Como dois Nothing comparam iguais, dois Nothing precisam comparar também menor-ou-igual. Uma versão escrita à mão desse operador devolvia false, e a suíte de conformidade marcou 703 de 703 com o bug presente, porque o corpus não cobre esse caso. Ele foi pego por verificações separadas, derivadas do texto da especificação e não dos seus testes.

Os limites que vale declarar: a ferramenta analisa o seu documento com o próprio parser JSON do navegador, então um número grande demais para um double já chega arredondado antes de a consulta o ver; o padrão tem bastante a dizer sobre números interoperáveis e nada disso resgata um valor perdido na análise. As expressões regulares dentro de match e search seguem a RFC 9485, que é um subconjunto pequeno sem grupos de captura, lookahead ou retrorreferências; um padrão que as use não é uma I-Regexp válida e a função é definida para devolver false em vez de dar erro.

Por que é grátis?

O motor roda no seu navegador. Analisar uma consulta e percorrer um documento não custa nada na sua própria máquina, então não há servidor a pagar nem conta a criar.

Nada do que você cola é enviado, guardado ou registrado. O JSON que você está depurando costuma ser um payload real de um sistema real, e o jeito confiável de manter isso privado é nunca recebê-lo.