
Un fork de JSONPath de http://goessner.net/articles/JsonPath/
[](https://www.npmjs.com/package/jsonpath-plus)
[](badges/tests-badge.svg)
[](badges/coverage-badge.svg)
[](https://snyk.io/test/github/s3u/JSONPath)
<!--[](LICENSE-MIT.txt)-->
[](badges/licenses-badge.svg)
[](https://github.com/JSONPath-Plus/JSONPath/actions/workflows/node.js.yml)
<small>(véase también [licencias para dependencias de desarrollo](https://raw.githubusercontent.com/s3u/JSONPath/master/badges/licenses-badge-dev.svg?sanitize=true))</small>
# JSONPath Plus
Analiza, transforma y extrae selectivamente datos de documentos JSON
(y objetos JavaScript).
`jsonpath-plus` amplía la especificación original para añadir algunos
operadores adicionales y hace explícitos algunos comportamientos que la
original no especificaba.
Prueba la [demostración en el navegador](https://jsonpath-plus.github.io/JSONPath/demo/) o
[Runkit (Node)](https://npm.runkit.com/jsonpath-plus).
***Ten en cuenta: Este proyecto no se mantiene activamente en la actualidad. Podemos
aceptar PRs bien documentados o algunas actualizaciones sencillas, pero no buscamos
hacer correcciones ni añadir nuevas funcionalidades por nuestra cuenta.***
## Características
* **Compatible** con la especificación jsonpath original
* **Adiciones o ampliaciones** convenientes no incluidas en la especificación original:
* `^` para obtener el **padre** de un elemento coincidente
* `~` para obtener los **nombres de propiedades** de los elementos coincidentes (como array)
* **Selectores de tipo** para obtener:
* Tipos JSON básicos: `@null()`, `@boolean()`, `@number()`, `@string()`, `@array()`, `@object()`
* `@integer()`
* El tipo compuesto `@scalar()` (que también acepta `undefined` y
números no finitos al consultar objetos JavaScript, así como todos los tipos básicos no objeto/no función)
* `@other()` utilizable junto con un `otherTypeCallback` definido por el usuario
* Tipos no JSON que sin embargo pueden usarse al consultar
objetos JavaScript no JSON (`@undefined()`, `@function()`, `@nonFinite()`)
* **Selectores abreviados** `@path`/`@parent`/`@property`/`@parentProperty`/`@root` dentro de filtros
* **Escapado**
* `` ` `` para escapar la secuencia restante
* Sintaxis `@['...']`/`?@['...']` para escapar caracteres especiales dentro de
nombres de propiedades en filtros
* Documenta `$..` (**obtener todos los componentes padre**)
* Formatos de exportación **ESM** y **UMD**
* Además de los valores consultados, **puede devolver diversa metainformación**
incluyendo rutas o punteros al valor, así como el objeto
padre y el nombre de la propiedad padre (para permitir su modificación).
* **Utilidades para convertir** entre rutas, arrays y punteros
* Opción para **prevenir evaluaciones** permitidas en la especificación original o proporcionar
un **sandbox** para los valores evaluados.
* Opción para **callback para manejar resultados** a medida que se obtienen.
## Benchmarking
`jsonpath-plus` es consistentemente eficiente tanto con conjuntos de datos grandes como pequeños en comparación con otras bibliotecas de consulta json según [json-querying-performance-testing](https://github.com/andykais/json-querying-performance-testing). Puedes verificar estos hallazgos [ejecutando el proyecto tú mismo](https://github.com/andykais/json-querying-performance-testing#how-to-run) y añadiendo más casos de rendimiento.
## Instalación
```shell
npm install jsonpath-plus
```
## Configuración
### Node.js
```js
const {JSONPath} = require('jsonpath-plus');
const result = JSONPath({path: '...', json});
```
### Navegador
Para uso en el navegador puedes incluir directamente `dist/index-browser-umd.cjs`; no
se necesita magia de Browserify:
```html
<script src="node_modules/jsonpath-plus/dist/index-browser-umd.cjs"></script>
<script>
const result = JSONPath.JSONPath({path: '...', json: {}});
</script>
```
### ESM (Navegadores modernos)
También puedes usar importaciones 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 (Empaquetadores)
O si estás empaquetando tu JavaScript (por ejemplo, con Rollup), simplemente usa,
teniendo en cuenta que [`mainFields`](https://github.com/rollup/plugins/tree/master/packages/node-resolve#mainfields)
debe incluir `browser` para compilaciones de navegador (para Node, el valor predeterminado, que
comprueba `module`, debería estar bien):
```js
import {JSONPath} from 'jsonpath-plus';
const result = JSONPath({path: '...', json});
```
## Uso
La firma completa disponible es:
```
const result = JSONPath([options,] path, json, callback, otherTypeCallback);
```
Los argumentos `path`, `json`, `callback` y `otherTypeCallback`
también pueden expresarse (junto con cualquier otra de las
propiedades disponibles) en `options`.
Ten en cuenta que `result` contendrá todos los elementos encontrados (opcionalmente
envueltos en un array), mientras que `callback` puede usarse si
deseas realizar alguna operación a medida que se descubre cada elemento, con
la función callback ejecutándose de 0 a N veces dependiendo
del número de elementos independientes que se encuentren en el resultado.
Consulta la documentación a continuación para más información sobre los argumentos disponibles de `JSONPath`.
Consulta también la [documentación de la API](https://jsonpath-plus.github.io/JSONPath/docs/ts/).
### Propiedades
Las propiedades que pueden proporcionarse en el objeto de opciones o en el
método evaluate (como primer argumento) incluyen:
- ***path*** (**obligatorio**) - La expresión JSONPath como una cadena
(normalizada o no normalizada) o un array
- ***json*** (**obligatorio**) - El objeto JSON a evaluar (ya sea de
tipo null, boolean, number, string, object o array).
- ***autostart*** (**por defecto: true**) - Si se proporciona como `false`,
se puede llamar al método `evaluate` manualmente.
- ***flatten*** (**por defecto: false**) - Si el array de resultados devuelto
se aplanará a un array de una sola dimensión.
- ***resultType*** (**por defecto: "value"**) - Puede ser una forma insensible a mayúsculas y minúsculas de
"value", "path", "pointer", "parent" o "parentProperty" para determinar
respectivamente si devolver los resultados como los valores de los elementos encontrados,
como sus rutas absolutas, como [JSON Pointers](https://tools.ietf.org/html/rfc6901)
a las rutas absolutas, como sus objetos padre, o como el nombre de la
propiedad de su padre. Si se establece en "all", todos estos tipos se devolverán en
un objeto con el tipo como nombre de clave.
- ***sandbox*** (**por defecto: {}**) - Mapa clave-valor de variables que estarán
disponibles para evaluaciones de código como expresiones de filtrado. (Ten en cuenta
que la ruta y el valor actuales también estarán disponibles para esas
expresiones; consulta la sección de Sintaxis para más detalles.)
- ***wrap*** (**por defecto: true**) - Si se deben envolver o no los resultados
en un array. Si `wrap` se establece en `false`, y no se encuentran resultados,
se devolverá `undefined` (en lugar de un array vacío cuando
`wrap` se establece en true). Si `wrap` se establece en `false` y se encuentra un único
resultado que no es un array, ese resultado será el único elemento devuelto
(no dentro de un array). Sin embargo, se seguirá devolviendo un array si se encuentran múltiples
resultados. Para evitar ambigüedades (en el caso en que
sea necesario distinguir entre un resultado que es un fallo
y uno que es un array vacío), se recomienda cambiar el
valor por defecto a `false`.
- ***eval*** (**por defecto: "safe"**) - Método de evaluación de scripts.
`safe`: En el navegador, usará un motor de scripting mínimo que no
usa `eval` ni `Function` y cumple con la Content Security Policy. En NodeJS,
no tiene efecto y es equivalente a native ya que el scripting es seguro allí.
`native`: usa las capacidades de scripting nativas. Es decir, `eval` o
`Function` inseguros en el navegador y `vm.Script` en nodejs. `false`: Deshabilita las expresiones
de evaluación de JavaScript y lanza excepciones cuando se intentan estas expresiones.
`callback [ (code, context) => value]`: Una implementación personalizada que se llama
con `code` y `context` como argumentos para devolver el valor evaluado.
`class`: Una clase que se crea con `code` como argumento del constructor y el código
se evalúa llamando a `runInNewContext` con `context`.
``
- ***ignoreEvalErrors*** (**por defecto: false**) - Ignorar los errores encontrados durante
la evaluación de scripts.
- ***parent*** (**por defecto: null**) - En el caso de que una consulta pudiera
hacerse para devolver el nodo raíz, esto permite que el padre de ese nodo raíz
se devuelva dentro de los resultados.
- ***parentProperty*** (**por defecto: null**) - En el caso de que una consulta
pudiera hacerse para devolver el nodo raíz, esto permite que la `parentProperty`
de ese nodo raíz se devuelva dentro de los resultados. Puede ser un nombre de propiedad
de tipo string o un índice numérico de array.
- ***callback*** (**por defecto: (ninguno)**) - Si se proporciona, se llamará a un callback
inmediatamente tras la recuperación de un valor de punto final. Los tres argumentos
proporcionados serán el valor del payload (según `resultType`),
el tipo del payload (ya sea un "value" normal o un nombre de "property"),
y un objeto payload completo (con todos los `resultType`s).
- ***otherTypeCallback*** (**por defecto: \<Una función que lanza un error**
**cuando se encuentra @other()\>**) - En la ausencia actual de soporte de JSON
Schema, se pueden determinar tipos más allá de los tipos integrados
añadiendo el operador `@other()` al final de la consulta. Si se encuentra dicha
ruta, se invocará `otherTypeCallback` con el
valor del elemento, su ruta, su padre y el nombre de la propiedad de su padre,
y debería devolver un booleano que indique si el valor proporcionado
pertenece al tipo "other" o no (o puede manejar transformaciones y
devolver false).
- ***customTypes*** (**por defecto: {}**) - Un mapa clave-valor de nombres de tipos a funciones.
Esto permite crear operadores de tipo personalizados que pueden usarse en consultas
(por ejemplo, `@myType()`). La función se invocará con el valor del elemento,
su ruta, su padre y el nombre de la propiedad de su padre. Debería devolver un
booleano que indique si el valor proporcionado coincide con el tipo personalizado. También
puede establecerse en:
1. El valor del import `jsonpath-plus/src/structuredCloningTypes.js` que predefine los siguientes tipos:
@NaN(), @BigIntObject(), @Date(), @Set(), @Map(), @RegExp(),
@Blob(optionalMimeType), @File(optionalMimeType), @Boolean(), @Number(),
@String(), @Infinity(), @negativeInfinity(), @negativeZero(),
@DOMException(), @Error(), @EvalError(), @RangeError(), @ReferenceError(),
@SyntaxError(), @TypeError(), @URIError(), @AggregateError(),
@QuotaExceededError(), @WebTransportError(), @FileList, @ArrayBuffer(),
@DataView(), @ImageData(), @ImageBitmap(), @Int8Array(), @Uint8Array(),
@Uint8ClampedArray(), @Int16Array(), @Uint16Array(), @Int32Array(),
@Uint32Array(), @Float32Array(), @Float64Array(), @BigInt64Array(),
@BigUint64Array(), @Float16Array, @DOMMatrix(), @DOMMatrixReadOnly(),
@DOMPoint(), @DOMPointReadOnly(), @DOMRect, @DOMRectReadOnly(),
@DOMQuad(), @CryptoKey(), @AudioData(), @EncodedAudioChunk(),
@EncodedVideoChunk(), @VideoFrame(), @CropTarget,
@FileSystemDirectoryHandle(), @FileSystemFileHandle(),
@GPUCompilationInfo(), @GPUCompilationMessage(),
@GPUPipelineError(), @RTCCertificate(), @RTCEncodedAudioFrame(),
@RTCEncodedVideoFrame()
2. El valor del import `jsonpath-plus/src/javascriptTypes.js` que predefine los siguientes tipos:
@Generator(), @AsyncGenerator(), @GeneratorFunction(),
@AsyncGeneratorFunction(), @Iterable(), @AsyncIterable(), @Iterator()
### Métodos de instancia
- ***evaluate(path, json, callback, otherTypeCallback)*** O
***evaluate({path: \<path\>, json: \<json object\>, callback:***
***\<callback function\>, otherTypeCallback:***
***\<otherTypeCallback function\>})*** - Este método solo es
necesario si la propiedad `autostart` se establece en `false`. Puede
usarse para evaluaciones repetidas usando la misma configuración.
Además de las propiedades listadas, el último patrón de método puede
aceptar cualquiera de las otras propiedades de instancia permitidas (excepto
`autostart`, que no tendría relevancia aquí).
### Propiedades y métodos de clase
- ***JSONPath.clearCache()*** - Limpia las rutas analizadas y los scripts compilados
almacenados en caché internamente. El contenido de la caché no se expone; llama a este método cuando
se necesite invalidar la caché.
- ***JSONPath.toPathArray(pathAsString)*** - Acepta una ruta normalizada o
no normalizada como string y la convierte en un array: por
ejemplo, `['$', 'aProperty', 'anotherProperty']`.
- ***JSONPath.toPathString(pathAsArray)*** - Acepta un array de ruta y
lo convierte en un string de ruta normalizado. El string tendrá una forma
como: `$['aProperty']['anotherProperty][0]`. Las construcciones terminales de JSONPath
`~` y `^` y los operadores de tipo como `@string()` se
eliminan silenciosamente.
- ***JSONPath.toPointer(pathAsArray)*** - Acepta un array de ruta y
lo convierte en un [JSON Pointer](https://tools.ietf.org/html/rfc6901).
El string tendrá una forma como: `/aProperty/anotherProperty/0`
(con cualquier carácter interno `~` y `/` escapado según la especificación de JSON
Pointer). Las construcciones terminales de JSONPath `~` y `^` y
los operadores de tipo como `@string()` se eliminan silenciosamente.
## Sintaxis mediante ejemplos
Dado el siguiente JSON, tomado 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
}
}
}
```
y la siguiente representación 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>
```
Ten en cuenta que los ejemplos de XPath a continuación no distinguen entre
recuperar elementos y su contenido de texto (excepto cuando resulta útil para
comparaciones o para evitar ambigüedad). Nota: para probar los ejemplos de XPath
(incluidos los de 2.0), [esta demo](http://videlibri.sourceforge.net/cgi-bin/xidelcgi)
puede ser útil (configurada en `xml` o `xml-strict`).
| XPath | JSONPath | Resultado | Notas |
|-------------------------------------------------------------------------------------|---------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `/store/book/author` | `$.store.book[*].author` | Los autores de todos los libros de la tienda | También se puede representar sin el `$.` como `store.book[*].author` (aunque esto no está presente en la especificación original); ten en cuenta que algunos caracteres literales (`$` y `@`) requieren escape, sin embargo |
| `//author` | `$..author` | Todos los autores | |
| `/store/*` | `$.store.*` | Todas las cosas en la tienda, que son sus libros (un array de libros) y una bicicleta roja (un objeto bicicleta). | |
| `/store//price` | `$.store..price` | El precio de todo en la tienda. | |
| `//book[3]` | `$..book[2]` | El tercer libro (objeto libro) | |
| `//book[last()]` | `$..book[(@.length-1)]` <br> `$..book[-1:]` | El último libro en orden. | Para acceder a una propiedad con un carácter especial, utiliza `[(@['...'])]` para el filtro (esta característica particular no está presente en la especificación original) |
| `//book[position()<3]` | `$..book[0,1]` <br> `$..book[:2]` | Los dos primeros libros | |
| `//book/*[self::category\|self::author]` o `//book/(category,author)` en XPath 2.0 | `$..book[0][category,author]` | Las categorías y autores de todos los libros | |
| `//book[isbn]` | `$..book[?(@.isbn)]` | Filtra todos los libros con un número ISBN | Para acceder a una propiedad con un carácter especial, utiliza `[?@['...']]` para el filtro (esta característica particular no está presente en la especificación original) |
| `//book[price<10]` | `$..book[?(@.price<10)]` | Filtra todos los libros más baratos que 10 | |
| `//*[name() = 'price' and . != 8.95]` | `$..*[?(@property === 'price' && @ !== 8.95)]` | Obtiene todos los valores de propiedad de objetos cuya propiedad es price y que no es igual a 8.95 | Con el `@` solo permitiendo filtrar objetos por valor de propiedad (no necesariamente dentro de arrays), puedes añadir `^` después de la expresión para llegar al objeto que posee las propiedades filtradas |
| `/` | `$` | La raíz del objeto JSON (es decir, el objeto completo en sí mismo) | Para obtener un `$` literal (por sí solo o en cualquier parte de la ruta), debes usar el escape con backtick |
| `//*/*\|//*/*/text()` | `$..*` | Todos los elementos (y texto) bajo la raíz en un documento XML. Todos los miembros de una estructura JSON bajo la raíz. | |
| `//*` | `$..` | Todos los elementos en un documento XML. Todos los componentes padre de una estructura JSON incluyendo la raíz. | Este comportamiento no fue especificado directamente en la especificación original |
---
[Read more](https://github.com/jsonpath-plus/jsonpath)