
JSONPath v10.4.1
Um fork do JSONPath de http://goessner.net/articles/JsonPath/
(veja também licenças para deps. de desenvolvimento)
JSONPath Plus
Analise, transforme e extraia seletivamente dados de documentos JSON (e objetos JavaScript).
jsonpath-plus expande a especificação original para adicionar alguns operadores adicionais e torna explícitos alguns comportamentos que a original não especificou.
Experimente a demo no navegador ou o Runkit (Node).
Por favor, observe: este projeto não está atualmente em manutenção ativa. Podemos aceitar PRs bem documentados ou algumas atualizações simples, mas não estamos procurando fazer correções ou adicionar novos recursos por conta própria.
Recursos
- Compatível com a especificação jsonpath original
- Adições ou elaborações convenientes não fornecidas na especificação original:
^para obter o pai de um item correspondente~para obter os nomes de propriedades dos itens correspondentes (como array)- Seletores de tipo para obter:
- Tipos JSON básicos:
@null(),@boolean(),@number(),@string(),@array(),@object() @integer()- O tipo composto
@scalar()(que também aceitaundefinede números não finitos ao consultar objetos JavaScript, bem como todos os tipos básicos não-objeto/não-função) @other()utilizável em conjunto com umotherTypeCallbackdefinido pelo usuário- Tipos não JSON que podem, ainda assim, ser usados ao consultar objetos JavaScript não JSON (
@undefined(),@function(),@nonFinite())
- Tipos JSON básicos:
@path/@parent/@property/@parentProperty/@rootseletores abreviados em filtros- Escapamento
`para escapar a sequência restante- Sintaxe
@['...']/?@['...']para escapar caracteres especiais em nomes de propriedades em filtros
- Documenta
$..(obtendo todos os componentes-pai)
- Formatos de exportação ESM e UMD
- Além dos valores consultados, pode retornar várias meta-informações incluindo caminhos ou ponteiros para o valor, bem como o objeto pai e o nome da propriedade pai (para permitir modificação).
- Utilitários para conversão entre caminhos, arrays e ponteiros
- Opção para impedir avaliações permitidas na especificação original ou fornecer uma sandbox para valores avaliados.
- Opção para callback manipular os resultados conforme são obtidos.
Benchmarking
jsonpath-plus tem desempenho consistentemente bom com conjuntos de dados grandes e pequenos comparado a outras bibliotecas de consulta json, conforme json-querying-performance-testing. Você pode verificar essas conclusões executando o projeto você mesmo e adicionando mais casos de desempenho.
Instalação```shell
npm install jsonpath-plus
## Configuração
### Node.js```js
const {JSONPath} = require('jsonpath-plus');
const result = JSONPath({path: '...', json});
Navegador
Para uso no navegador, você pode incluir diretamente dist/index-browser-umd.cjs; não
é necessária nenhuma mágica do Browserify:```html
### ESM (Navegadores modernos)
Você também pode usar imports de módulos ES6 (para navegadores modernos):```html
<script type="module">
import {
JSONPath
} from './node_modules/jsonpath-plus/dist/index-browser-esm.js';
const result = JSONPath({path: '...', json: {}});
</script>
ESM (Empacotadores)
Ou se você está empacotando seu JavaScript (por exemplo, com Rollup), basta usar,
observando que mainFields
deve incluir browser para builds de navegador (para Node, o padrão, que
verifica module, deve ser suficiente):```js
import {JSONPath} from 'jsonpath-plus';
const result = JSONPath({path: '...', json});
## Uso
A assinatura completa disponível é:```
const result = JSONPath([options,] path, json, callback, otherTypeCallback);
Os argumentos path, json, callback e otherTypeCallback
podem ser expressos alternativamente (junto com quaisquer outras
propriedades disponíveis) em options.
Note que result conterá todos os itens encontrados (opcionalmente
envolvidos em um array), enquanto callback pode ser usado se
desejar realizar alguma operação à medida que cada item for
descoberto, com a função de callback sendo executada de 0 a N vezes,
dependendo do número de itens independentes a serem encontrados no resultado.
Consulte a documentação abaixo para saber mais sobre os argumentos disponíveis de JSONPath.
Veja também a documentação da API.
Propriedades
As propriedades que podem ser fornecidas no objeto de opções ou
no método evaluate (como primeiro argumento) incluem:
- path (obrigatório) - A expressão JSONPath como uma (normalizada ou não normalizada) string ou array
- json (obrigatório) - O objeto JSON a avaliar (seja do tipo null, boolean, number, string, object ou array).
- autostart (padrão: true) - Se isto for fornecido como
false, pode-se chamar o métodoevaluatemanualmente. - flatten (padrão: false) - Indica se o array de resultados retornado será achatado para um array de uma única dimensão.
- resultType (padrão: "value") - Pode ser a forma sem diferenciar maiúsculas de minúsculas de "value", "path", "pointer", "parent" ou "parentProperty" para determinar respectivamente se os resultados devem ser retornados como os valores dos itens encontrados, como seus caminhos absolutos, como JSON Pointers para os caminhos absolutos, como seus objetos pai, ou como o nome da propriedade do pai. Se definido como "all", todos esses tipos serão retornados em um objeto com o tipo como nome da chave.
- sandbox (padrão: {}) - Mapa chave-valor de variáveis que estarão disponíveis para avaliações de código, como expressões de filtro. (Observe que o caminho e o valor atuais também estarão disponíveis para essas expressões; consulte a seção Sintaxe para detalhes.)
- wrap (padrão: true) - Indica se os resultados devem ou não ser envolvidos
em um array. Se
wrapfor definido comofalsee nenhum resultado for encontrado,undefinedserá retornado (em vez de um array vazio quandowrapfor definido como true). Sewrapfor definido comofalsee um único resultado não-array for encontrado, esse resultado será o único item retornado (não dentro de um array). Um array ainda será retornado se vários resultados forem encontrados, no entanto. Para evitar ambiguidades (no caso em que seja necessário distinguir entre um resultado que é uma falha e um que é um array vazio), é recomendável alterar o padrão parafalse. - eval (padrão: "safe") - Método de avaliação de script.
safe: No navegador, usará um mecanismo de script mínimo que não usaevalnemFunctione satisfaz a Política de Segurança de Conteúdo. No NodeJS, não tem efeito e é equivalente ao native, pois scripting é seguro lá.native: usa os recursos nativos de scripting. Ou seja,evalouFunctioninseguros no navegador evm.Scriptno nodejs.false: Desabilita as expressões de avaliação de JavaScript e lança exceções quando tais expressões são tentadas.callback [ (code, context) => value]: Uma implementação personalizada que é chamada comcodeecontextcomo argumentos para retornar o valor avaliado.class: Uma classe criada comcodecomo argumento do construtor e o código é avaliado chamandorunInNewContextcomcontext. `` - ignoreEvalErrors (padrão: false) - Ignora erros encontrados durante a avaliação do script.
- parent (padrão: null) - No caso de uma consulta poder ser feita para retornar o nó raiz, isto permite que o pai desse nó raiz seja retornado nos resultados.
- parentProperty (padrão: null) - No caso de uma consulta
poder ser feita para retornar o nó raiz, isto permite que o
parentPropertydesse nó raiz seja retornado nos resultados. Pode ser um nome de propriedade do tipo string ou um índice numérico de array. - callback (padrão: (nenhum)) - Se fornecido, um callback será
chamado imediatamente após a recuperação de um valor de ponto final. Os três argumentos
fornecidos serão o valor do payload (de acordo com
resultType), o tipo do payload (se é um "value" normal ou um "property" name), e um objeto de payload completo (com todos osresultTypes). - otherTypeCallback (padrão: <Uma função que lança um erro
quando @other() é encontrado>) - Na atual ausência de suporte a JSON
Schema, pode-se determinar tipos além dos tipos embutidos
adicionando o operador
@other()ao final de sua consulta. Se tal caminho for encontrado, ootherTypeCallbackserá invocado com o valor do item, seu caminho, seu pai e o nome da propriedade de seu pai, e deve retornar um booleano indicando se o valor fornecido pertence ou não ao tipo "other" (ou pode lidar com transformações e retornar false).
Métodos de instância
- evaluate(path, json, callback, otherTypeCallback) OU
evaluate({path: <path>, json: <json object>, callback:
<callback function>, otherTypeCallback:
<otherTypeCallback function>}) - Este método só é
necessário se a propriedade
autostartestiver definida comofalse. Ele pode ser usado para avaliações repetidas usando a mesma configuração. Além das propriedades listadas, o último padrão de método pode aceitar qualquer uma das outras propriedades de instância permitidas (excetoautostart, que não teria relevância aqui).
Propriedades e métodos de classe
- JSONPath.clearCache() - Limpa os caminhos analisados e os scripts compilados armazenados em cache internamente. O conteúdo do cache não é exposto; chame este método quando for necessário invalidar o cache.
- JSONPath.toPathArray(pathAsString) - Aceita um caminho normalizado ou
não normalizado como string e o converte em um array: por
exemplo,
['$', 'aProperty', 'anotherProperty']. - JSONPath.toPathString(pathAsArray) - Aceita um array de caminho e
o converte em uma string de caminho normalizada. A string estará em uma forma
como:
$['aProperty']['anotherProperty][0]. As construções terminais do JSONPath~e^e os operadores de tipo como@string()são silenciosamente removidos. - JSONPath.toPointer(pathAsArray) - Aceita um array de caminho e
o converte em um JSON Pointer.
A string estará em uma forma como:
/aProperty/anotherProperty/0(com quaisquer caracteres internos~e/escapados de acordo com a especificação JSON Pointer). As construções terminais do JSONPath~e^e os operadores de tipo como@string()são silenciosamente removidos.
Sintaxe através de exemplos
Dado o seguinte JSON, obtido de http://goessner.net/articles/JsonPath/:```json { "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ], "bicycle": { "color": "red", "price": 19.95 } } }
e a seguinte representação XML:```xml
<store>
<book>
<category>reference</category>
<author>Nigel Rees</author>
<title>Sayings of the Century</title>
<price>8.95</price>
</book>
<book>
<category>fiction</category>
<author>Evelyn Waugh</author>
<title>Sword of Honour</title>
<price>12.99</price>
</book>
<book>
<category>fiction</category>
<author>Herman Melville</author>
<title>Moby Dick</title>
<isbn>0-553-21311-3</isbn>
<price>8.99</price>
</book>
<book>
<category>fiction</category>
<author>J. R. R. Tolkien</author>
<title>The Lord of the Rings</title>
<isbn>0-395-19395-8</isbn>
<price>22.99</price>
</book>
<bicycle>
<color>red</color>
<price>19.95</price>
</bicycle>
</store>
Observe que os exemplos de XPath abaixo não distinguem entre
recuperar elementos e seu conteúdo de texto (exceto quando útil para
comparações ou para evitar ambiguidade). Nota: para testar os exemplos de XPath
(incluindo os 2.0), esta demonstração
pode ser útil (defina para xml ou xml-strict).| XPath | JSONPath | Resultado | Observações |
|---|---|---|---|
| /store/book/author | $.store.book[*].author | Os autores de todos os livros na loja | Também pode ser representado sem o $. como store.book[*].author (embora isso não esteja presente na especificação original); note que alguns literais de caractere ($ e @) exigem escape, no entanto |
| //author | $..author | Todos os autores | |
| /store/* | $.store.* | Todas as coisas na loja, que são seus livros (um array de livros) e uma bicicleta vermelha (um objeto de bicicleta). | |
| /store//price | $.store..price | O preço de tudo na loja. | |
| //book[3] | $..book[2] | O terceiro livro (objeto de livro) | |
| //book[last()] | $..book[(@.length-1)]
$..book[-1:] | O último livro em ordem. | Para acessar uma propriedade com um caractere especial, utilize [(@['...'])] para o filtro (este recurso específico não está presente na especificação original) |
| //book[position()<3] | $..book[0,1]
$..book[:2] | Os dois primeiros livros | |
| //book/*[self::category\|self::author] or //book/(category,author) in XPath 2.0 | $..book[0][category,author] | As categorias e autores de todos os livros | |
| //book[isbn] | $..book[?(@.isbn)] | Filtrar todos os livros que possuem um número ISBN | Para acessar uma propriedade com um caractere especial, utilize [?@['...']] para o filtro (este recurso específico não está presente na especificação original) |
| //book[price<10] | $..book[?(@.price<10)] | Filtrar todos os livros mais baratos que 10 | |
| //*[name() = 'price' and . != 8.95] | $..*[?(@property === 'price' && @ !== 8.95)] | Obter todos os valores de propriedade de objetos cuja propriedade é price e que não seja igual a 8.95 | Com @ puro permitindo filtrar objetos por valor de propriedade (não necessariamente dentro de arrays), você pode adicionar ^ após a expressão para obter o objeto que possui as propriedades filtradas |
| / | $ | A raiz do objeto JSON (ou seja, o próprio objeto inteiro) | Para obter um $ literal (sozinho ou em qualquer lugar no caminho), você deve usar o escape com crase |
| //*/*\|//*/*/text() | $..* | Todos os Elementos (e texto) abaixo da raiz em um documento XML. Todos os membros de uma estrutura JSON abaixo da raiz. | |
| //* | $.. | Todos os Elementos em um documento XML. Todos os componentes pais de uma estrutura JSON incluindo a raiz. | Este comportamento não foi especificado diretamente na especificação original |
| //*[price>19]/.. | $..[?(@.price>19)]^ | Pai dos itens específicos com preço maior que 19 (ou seja, o valor da loja como pai da bicicleta e o array de livros como pai de um livro individual) | Pai (circunflexo) não está presente na especificação original |
| /store/*/name() (in XPath 2.0) | $.store.*~ | Os nomes das propriedades do sub-objeto da loja ("book" e "bicycle"). Útil com propriedades curinga. | Nome de propriedade (til) não está presente na especificação original |
| /store/book[not(. is /store/book[1])] (in XPath 2.0) | $.store.book[?(@path !== "$['store']['book'][0]")] | Todos os livros exceto aquele no caminho que aponta para o primeiro | @path não está presente na especificação original |
| //book[parent::*/bicycle/color = "red"]/category | $..book[?(@parent.bicycle && @parent.bicycle.color === "red")].category | Obtém todas as categorias de livros onde o objeto pai do livro tem um filho bicicleta cuja cor é vermelha (ou seja, todos os livros) | @parent não está presente na especificação original |
| //book/*[name() != 'category'] | $..book.*[?(@property !== "category")] | Obtém todos os filhos de "book" exceto os de "category" | @property não está presente na especificação original |
| //book[position() != 1] | $..book[?(@property !== 0)] | Obtém todos os livros cuja propriedade (que, por estarmos alcançando o interior de um array, é o índice numérico) não é 0 | @property não está presente na especificação original |
| /store/*/*[name(parent::*) != 'book'] | $.store.*[?(@parentProperty !== "book")] | Obtém os netos da loja cuja propriedade pai não é book (ou seja, os filhos da bicicleta, "color" e "price") | @parentProperty não está presente na especificação original |
| //book[count(preceding-sibling::*) != 0]/*/text() | $..book.*[?(@parentProperty !== 0)] | Obter os valores de propriedade de todas as instâncias de livro em que a propriedade pai desses valores (ou seja, o índice do array que contém o objeto pai do item de livro) não é 0 | @parentProperty não está presente na especificação original |
| //book[price = /store/book[3]/price] | $..book[?(@.price === @root.store.book[2].price)] | Filtrar todos os livros cujo preço seja igual ao preço do terceiro livro | @root não está presente na especificação original |
| //book/../*[. instance of element(*, xs:decimal)] (in XPath 2.0) | $..book..*@number() | Obter os valores numéricos dentro do array de livros | @number(), os outros tipos básicos (@boolean(), @string()), outros tipos derivados de baixo nível (@null(), @object(), @array()), o tipo adicionado pelo JSONSchema, @integer(), o tipo composto @scalar() (que também aceita undefined e números não finitos para objetos JavaScript, bem como todos os tipos básicos não-objeto/não-função), o tipo @other(), a ser usado em conjunto com um callback definido pelo usuário (veja otherTypeCallback) e os seguintes tipos não-JSON que podem, no entanto, ser usados com JSONPath ao consultar objetos JavaScript não-JSON (@undefined(), @function(), @nonFinite()) não estão presentes na especificação original |
| //book/*[name() = 'category' and matches(., 'tion$')] (XPath 2.0) | $..book.*[?(@property === "category" && @.match(/TION$/i))] | Todas as categorias de livros que correspondem à regex (terminam em 'TION' sem diferenciar maiúsculas de minúsculas) | @property não está presente na especificação original. |
| //book/*[matches(name(), 'bn$')]/parent::* (XPath 2.0) | $..book.*[?(@property.match(/bn$/i))]^ | Todos os livros que possuem uma propriedade que corresponde à regex (terminam em 'TION' sem diferenciar maiúsculas de minúsculas) | @property não está presente na especificação original. Nota: Usa o seletor pai ^ no final da expressão para retornar ao objeto pai; sem o seletor pai, ele corresponde aos dois valores de chave isbn. |
| | ` (e.g., `$ para corresponder a uma propriedade literalmente chamada $) | Escapa toda a sequência seguinte (para ser tratada como literal) | ` não está presente na especificação original; para obter uma crase literal, use uma crase adicional para escapar |Quaisquer variáveis adicionais fornecidas como propriedades na opção
de objeto opcional "sandbox" também estão disponíveis para avaliações
(baseadas em parênteses).
Possíveis fontes de confusão para usuários de XPath
- Em JSONPath, uma expressão de filtro, além de seu
@ser uma referência aos seus filhos, na verdade também seleciona os filhos imediatos, enquanto em XPath, as condições de filtro não selecionam os filhos, mas delimitam quais dos seus nós pais serão obtidos no resultado. - Em JSONPath, os índices de array são, como em JavaScript, baseados em 0 (eles começam em 0), enquanto em XPath, são baseados em 1.
- Em JSONPath, os testes de igualdade utilizam (conforme JavaScript) múltiplos sinais de igual enquanto em XPath, usam um único sinal de igual.
Interface de linha de comando
Uma interface de linha de comando (CLI) básica é fornecida. Acesse-a usando npx jsonpath-plus <json-file> <jsonpath-query>.
Ideias
- Suporte a OR fora de filtros (como em XPath
|) e agrupamento. - Criar sintaxe para funcionar como filtros do XPath ao não selecionar filhos?
- Permitir opção equivalente a parentNode (mantendo toda a cadeia de objetos parent e parentProperty até a raiz)
Desenvolvimento
Executando os testes no Node:```shell npm test
Para testes no navegador:
- Sirva os arquivos js/html:```shell
npm run browser-test
- Visite http://localhost:8082/test/.
Segurança
Consulte SECURITY.md para considerações importantes de segurança e instruções sobre como reportar vulnerabilidades.