
Форк JSONPath с http://goessner.net/articles/JsonPath/
(см. также лицензии для dev. зависимостей)
Анализируйте, преобразовывайте и выборочно извлекайте данные из JSON-документов (и объектов JavaScript).
jsonpath-plus расширяет исходную спецификацию, добавляя некоторые дополнительные операторы и явно определяя поведение, которое оригинал не описывал.
Попробуйте браузерное демо или Runkit (Node).
Обратите внимание: этот проект в настоящее время не поддерживается активно. Мы можем принять хорошо документированные PR или некоторые простые обновления, но не планируем вносить исправления или добавлять новые функции самостоятельно.
^ для получения родителя совпадающего элемента~ для получения имён свойств совпадающих элементов (в виде массива)@null(), @boolean(), @number(), @string(), @array(), @object()@integer()@scalar() (который также принимает undefined и неконечные числа при запросах к объектам JavaScript, а также все базовые не-объектные/не-функциональные типы)@other(), используемый совместно с определённым пользователем otherTypeCallback@undefined(), @function(), @nonFinite())@path/@parent/@property/@parentProperty/@root внутри фильтров` для экранирования оставшейся последовательности@['...']/?@['...'] для экранирования специальных символов внутри имён свойств в фильтрах$.. (получение всех родительских компонентов)jsonpath-plus стабильно показывает высокую производительность как на больших, так и на малых наборах данных по сравнению с другими библиотеками запросов к JSON, согласно json-querying-performance-testing. Вы можете проверить эти результаты, запустив проект самостоятельно и добавив больше тестов производительности.
npm install jsonpath-plus
## Setup
### Node.js```js
const {JSONPath} = require('jsonpath-plus');
const result = JSONPath({path: '...', json});
Для использования в браузере вы можете напрямую подключить dist/index-browser-umd.cjs; никакой магии Browserify не требуется:```html
### ESM (современные браузеры)
Вы также можете использовать импорт ES6-модулей (для современных браузеров):```html
<script type="module">
import {
JSONPath
} from './node_modules/jsonpath-plus/dist/index-browser-esm.js';
const result = JSONPath({path: '...', json: {}});
</script>
Или, если вы собираете свой JavaScript (например, с помощью Rollup), просто используйте,
учитывая, что mainFields
должен включать browser для браузерных сборок (для Node значение по умолчанию, которое
проверяет module, должно подойти):```js
import {JSONPath} from 'jsonpath-plus';
const result = JSONPath({path: '...', json});
## Использование
Полная доступная сигнатура:```
const result = JSONPath([options,] path, json, callback, otherTypeCallback);
Аргументы path, json, callback и otherTypeCallback
могут быть альтернативно выражены (наряду с любыми другими из
доступных свойств) в options.
Обратите внимание, что result будет содержать все найденные элементы (при необходимости
обёрнутые в массив), тогда как callback можно использовать, если вы
хотите выполнить какую-либо операцию по мере обнаружения каждого элемента, при этом
функция обратного вызова будет выполнена от 0 до N раз в зависимости
от количества независимых элементов, которые необходимо найти в результате.
Подробнее о доступных аргументах JSONPath см. в документации ниже.
См. также документацию по API.
Свойства, которые можно указать в объекте options или в методе evaluate (в качестве первого аргумента), включают:
false,
можно вызвать метод evaluate вручную.wrap установлен в false и результаты не найдены,
будет возвращено undefined (в отличие от пустого массива, когда
wrap установлен в true). Если wrap установлен в false и найден
единственный результат, не являющийся массивом, этот результат будет
единственным возвращаемым элементом (не внутри массива). Однако массив
всё равно будет возвращён, если найдено несколько результатов. Чтобы
избежать неоднозначности (в случае, когда необходимо различать результат,
являющийся ошибкой, и результат, являющийся пустым массивом), рекомендуется
изменить значение по умолчанию на false.safe: в браузере будет использоваться минимальный скриптовый движок, который
не использует eval или Function и соответствует политике безопасности контента.
В NodeJS он не оказывает эффекта и эквивалентен native, поскольку скриптинг там безопасен.
native: использует нативные возможности скриптинга, т.е. небезопасные eval или
Function в браузере и vm.Script в Node.js. false: отключает выражения
вычисления JavaScript и вызывает исключения при попытке их использования.
callback [ (code, context) => value]: пользовательская реализация, которая вызывается
с code и context в качестве аргументов для возврата вычисленного значения.
class: класс, который создаётся с в качестве аргумента конструктора, а код
вычисляется путём вызова с .
``parentProperty
этого корневого узла в результатах. Это может быть строковое имя свойства
или числовой индекс массива.resultType),
тип полезной нагрузки (является ли она обычным «значением» или именем
«свойства») и полный объект полезной нагрузки (со всеми resultType).@other() в конец запроса. Если такой
путь встречается, otherTypeCallback будет вызван со
значением элемента, его путём, его родителем и именем свойства его родителя,
и он должен вернуть логическое значение, указывающее, принадлежит ли переданное значение
типу «other» или нет (или он может выполнять преобразования и
возвращать false).autostart установлено в false. Его
можно использовать для повторных вычислений с той же конфигурацией.
Помимо перечисленных свойств, второй вариант метода может
принимать любые другие допустимые свойства экземпляра (кроме
autostart, который здесь не имеет значения).['$', 'aProperty', 'anotherProperty'].$['aProperty']['anotherProperty][0]. Терминальные конструкции JSONPath
~ и ^, а также операторы типов, такие как @string(),
молча удаляются./aProperty/anotherProperty/0
(с любыми внутренними символами ~ и /, экранированными в соответствии со
спецификацией JSON Pointer). Терминальные конструкции JSONPath ~ и ^ и
операторы типов, такие как @string(), молча удаляются.Учитывая следующий JSON, взятый с 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 } } }
и следующее 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>
Обратите внимание, что примеры XPath ниже не различают
извлечение элементов и их текстового содержимого (кроме случаев, когда это полезно для
сравнений или для предотвращения неоднозначности). Примечание: для проверки примеров XPath
(включая версии 2.0), эта демонстрация
может быть полезна (установите значение xml или xml-strict).| XPath | JSONPath | Результат | Примечания |
|-------------------------------------------------------------------------------------|---------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| /store/book/author | $.store.book[*].author | Авторы всех книг в магазине | Также может быть представлено без $. как store.book[*].author (хотя этого нет в оригинальной спецификации); обратите внимание, что некоторые символьные литералы ($ и @) требуют экранирования, однако |
| //author | $..author | Все авторы | |
| /store/* | $.store.* | Все объекты в магазине: его книги (массив книг) и красный велосипед (объект велосипеда). | |
| /store//price | $.store..price | Цена всего в магазине. | |
| //book[3] | $..book[2] | Третья книга (объект книги) | |
| //book[last()] | $..book[(@.length-1)]
$..book[-1:] | Последняя книга по порядку. | Для доступа к свойству со специальным символом используйте [(@['...'])] для фильтра (эта конкретная функция отсутствует в оригинальной спецификации) |
| //book[position()<3] | $..book[0,1]
$..book[:2] | Первые две книги | |
| //book/*[self::category\|self::author] или //book/(category,author) в XPath 2.0 | $..book[0][category,author] | Категории и авторы всех книг | |
| //book[isbn] | $..book[?(@.isbn)] | Фильтр всех книг с номером ISBN | Для доступа к свойству со специальным символом используйте [?@['...']] для фильтра (эта конкретная функция отсутствует в оригинальной спецификации) |
| //book[price<10] | $..book[?(@.price<10)] | Фильтр всех книг дешевле 10 | |
| //*[name() = 'price' and . != 8.95] | $..*[?(@property === 'price' && @ !== 8.95)] | Получить все значения свойств объектов, чьё свойство — price и которое не равно 8.95 | С помощью голого @, позволяющего фильтровать объекты по значению свойства (не обязательно внутри массивов), вы можете добавить ^ после выражения, чтобы получить объект, обладающий отфильтрованными свойствами |
| / | $ | Корень JSON-объекта (т.е. сам объект целиком) | Чтобы получить литеральный $ (сам по себе или в любом месте пути), необходимо использовать экранирование обратным апострофом |
| //*/*\|//*/*/text() | $..* | Все элементы (и текст) под корнем в XML-документе. Все члены JSON-структуры под корнем. | |
| //* | $.. | Все элементы в XML-документе. Все родительские компоненты JSON-структуры, включая корень. | Это поведение не было напрямую указано в оригинальной спецификации |
| //*[price>19]/.. | $..[?(@.price>19)]^ | Родитель тех конкретных элементов с ценой больше 19 (т.е. значение store как родитель велосипеда и массив книг как родитель отдельной книги) | Родитель (карет) отсутствует в оригинальной спецификации |
| /store/*/name() (в XPath 2.0) | $.store.*~ | Имена свойств под-объекта store ("book" и "bicycle"). Полезно с подстановочными свойствами. | Имя свойства (тильда) отсутствует в оригинальной спецификации |
| /store/book[not(. is /store/book[1])] (в XPath 2.0) | $.store.book[?(@path !== "$['store']['book'][0]")] | Все книги, кроме той, что находится по пути, указывающему на первую | @path отсутствует в оригинальной спецификации |
| //book[parent::*/bicycle/color = "red"]/category | $..book[?(@parent.bicycle && @parent.bicycle.color === "red")].category | Получает все категории книг, где родительский объект книги имеет дочерний велосипед, чей цвет красный (т.е. все книги) | @parent отсутствует в оригинальной спецификации |
| //book/*[name() != 'category'] | $..book.*[?(@property !== "category")] | Получает всех детей "book", кроме тех, что относятся к "category" | @property отсутствует в оригинальной спецификации |
| //book[position() != 1] | $..book[?(@property !== 0)] | Получает все книги, чьё свойство (которое, поскольку мы обращаемся внутрь массива, является числовым индексом) не равно 0 | @property отсутствует в оригинальной спецификации |
| /store/*/*[name(parent::*) != 'book'] | $.store.*[?(@parentProperty !== "book")] | Получает внуков store, чьё родительское свойство не является book (т.е. дети велосипеда, "color" и "price") | @parentProperty отсутствует в оригинальной спецификации |
| //book[count(preceding-sibling::*) != 0]/*/text() | $..book.*[?(@parentProperty !== 0)] | Получить значения свойств всех экземпляров книг, где родительское свойство этих значений (т.е. индекс массива, содержащий родительский объект книги) не равно 0 | @parentProperty отсутствует в оригинальной спецификации |
| //book[price = /store/book[3]/price] | $..book[?(@.price === @root.store.book[2].price)] | Фильтр всех книг, чья цена равна цене третьей книги | @root отсутствует в оригинальной спецификации |
| //book/../*[. instance of element(*, xs:decimal)] (в XPath 2.0) | $..book..*@number() | Получить числовые значения внутри массива книг | @number(), другие базовые типы (@boolean(), @string()), другие низкоуровневые производные типы (@null(), @object(), @array()), добавленный JSONSchema тип @integer(), составной тип @scalar() (который также принимает undefined и неконечные числа для JavaScript-объектов, а также все базовые не-объектные/не-функциональные типы), тип @other(), используемый вместе с пользовательским обратным вызовом (см. otherTypeCallback), и следующие не-JSON типы, которые тем не менее можно использовать с JSONPath при запросах к не-JSON JavaScript-объектам (@undefined(), @function(), @nonFinite()), отсутствуют в оригинальной спецификации |
| //book/*[name() = 'category' and matches(., 'tion$')] (XPath 2.0) | $..book.*[?(@property === "category" && @.match(/TION$/i))] | Все категории книг, соответствующие регулярному выражению (заканчиваются на 'TION' без учёта регистра) | @property отсутствует в оригинальной спецификации. |
| //book/*[matches(name(), 'bn$')]/parent::* (XPath 2.0) | $..book.*[?(@property.match(/bn$/i))]^ | Все книги, имеющие свойство, соответствующее регулярному выражению (заканчивается на 'TION' без учёта регистра) | @property отсутствует в оригинальной спецификации. Примечание: использует родительский селектор ^ в конце выражения для возврата к родительскому объекту; без родительского селектора он сопоставляет два значения ключа isbn. |
| | ` (например, `$ для сопоставления свойства, буквально названного $) | Экранирует всю последующую последовательность (для обработки как литерала) | ` отсутствует в оригинальной спецификации; чтобы получить литеральный обратный апостроф, используйте дополнительный обратный апостроф для экранирования |Любые дополнительные переменные, предоставленные в качестве свойств необязательного
объекта sandbox, также доступны для (основанных на скобках)
вычислений.
@ является
ссылкой на его дочерние элементы, фактически также выбирает непосредственные
дочерние элементы, тогда как в XPath условия фильтра не выбирают дочерние элементы,
а ограничивают, какие из его родительских узлов будут получены в результате.Предоставляется базовый интерфейс командной строки (CLI). Доступ к нему осуществляется с помощью npx jsonpath-plus <json-file> <jsonpath-query>.
| в XPath) и группировки.Запуск тестов на Node:```shell npm test
Для тестов в браузере:
- Раздайте js/html файлы:```shell
npm run browser-test
Пожалуйста, ознакомьтесь с SECURITY.md для получения важных сведений о безопасности и инструкций по сообщению об уязвимостях.
coderunInNewContextcontext