Есть ли эквивалент JSON XQuery/XPath?

При поиске элементов в сложных массивах JSON и хэшах, например:

[
    { "id": 1, "name": "One", "objects": [
        { "id": 1, "name": "Response 1", "objects": [
            // etc.
        }]
    }
]

Есть ли какой-то язык запросов, который я могу использовать для поиска элемента in [0].objects where id = 3?

Ответ 1

Yup, он называется JSONPath:

Он также интегрирован в DOJO.

Ответ 2

Я думаю, что JSONQuery - это надмножество JSONPath и, следовательно, заменяет его в dojo. Затем также RQL.

Из Dojo документации:

JSONQuery - это расширенная версия JSONPath с дополнительными функциями для обеспечения безопасности, простоты использования и комплексного набора запросов данных инструменты, включая фильтрацию, рекурсивный поиск, сортировку, отображение, диапазон выбор и гибкие выражения с сопоставлениями подстановочных строк и различные операторы.

JSONselect имеет другую точку зрения на вопрос (CSS-селекторный, а не XPath) и имеет реализация JavaScript.

Ответ 3

Другие альтернативы, о которых я знаю,

  • JSONiq спецификация, которая определяет два подтипа языков: тот, который скрывает детали XML и предоставляет JS-подобный синтаксис, и тот, который обогащает синтаксис XQuery с конструкторами JSON и т.д. Zorba реализует JSONiq.
  • Corona, который построен поверх MarkLogic, предоставляет интерфейс REST для хранения, управления и поиска XML, JSON, Text и Двоичный контент.
  • MarkLogic 6 и более поздние версии предоставляют аналогичный интерфейс REST как Corona из коробки.
  • MarkLogic 8 и более поздние версии поддерживают JSON изначально как в среде JavaScript XQuery, так и на стороне сервера. Вы можете применить XPath к нему.

НТН.

Ответ 4

Попробуйте использовать JSPath

JSPath - это доменный язык (DSL), который позволяет вам перемещаться и находить данные в ваших документах JSON. Используя JSPath, вы можете выбрать элементы JSON для извлечения данных, которые они содержат.

JSPath для JSON, как XPath для XML.

Он сильно оптимизирован как для Node.js, так и для современных браузеров.

Ответ 5

Чтобы обобщить некоторые из текущих параметров для перемещения/фильтрации данных JSON и предоставить некоторые примеры синтаксиса...

  • JSPath
    .automobiles{.maker === "Honda" && .year > 2009}.model

  • json: select() (больше вдохновлен CSS-селекторами)
    .automobiles .maker:val("Honda") .model

  • JSONPath (больше вдохновил XPath)
    $.automobiles[?(@.maker='Honda')].model

Я думаю, что JSPath выглядит красивее, поэтому я собираюсь попытаться интегрировать его с моим приложением AngularJS + CakePHP.

(Я изначально опубликовал этот ответ в другом потоке, но подумал, что здесь тоже будет полезно.)

Ответ 6

XQuery может использоваться для запроса JSON при условии, что процессор поддерживает JSON. Это простой пример того, как BaseX можно использовать для поиска объектов с "id" = 1:

json:parse('[
    { "id": 1, "name": "One", "objects": [
        { "id": 1, "name": "Response 1", "objects": [ "etc." ] }
    ]}
]')//value[.//id = 1]

Ответ 7

Json Pointer, похоже, тоже получает поддержку.

Ответ 8

ObjectPath - это язык запросов, похожий на XPath или JSONPath, но гораздо более мощный благодаря встроенным арифметическим вычислениям, механизмам сравнения и встроенным алгоритмам, в функциях. См. Синтаксис:

Найдите в магазине все туфли красного цвета и цену менее 50

$.. обувь. * [цвет "красный" и цена < 50]

Ответ 9

Jsel является потрясающим и основан на реальном процессоре XPath. Он позволяет создавать выражения XPath для поиска любых типов данных JavaScript, а не только объектов (строки тоже).

Вы можете создавать собственные схемы и сопоставления, чтобы дать вам полный контроль над тем, как ваши данные могут быть перемещены движком XPath. Схема - это способ определения того, как элементы, дети, атрибуты и значения node определены в ваших данных. Затем вы можете создать свои собственные выражения.

Учитывая, что у вас была переменная с именем data, в которой содержался JSON из вопроса, вы можете использовать jsel для записи:

jsel(data).select("//*[@id=3]")

Это вернет любой node с атрибутом id 3. Атрибут - это любое значение примитива (строка, число, дата, регулярное выражение) внутри объекта.

Ответ 10

Defiant.js выглядит также довольно круто, вот простой пример:

var obj = {
        "car": [
            {"id": 10, "color": "silver", "name": "Volvo"},
            {"id": 11, "color": "red",    "name": "Saab"},
            {"id": 12, "color": "red",    "name": "Peugeot"},
            {"id": 13, "color": "yellow", "name": "Porsche"}
        ],
        "bike": [
            {"id": 20, "color": "black", "name": "Cannondale"},
            {"id": 21, "color": "red",   "name": "Shimano"}
        ]
    },
    search = JSON.search(obj, '//car[color="yellow"]/name');

console.log( search );
// ["Porsche"]

var reds = JSON.search(obj, '//*[color="red"]');

for (var i=0; i<reds.length; i++) {
    console.log( reds[i].name );
}
// Saab
// Peugeot
// Shimano

Ответ 11

@Naftule - с "defiant.js", можно запросить структуру JSON с выражениями XPath. Проверьте этот оценщик, чтобы получить представление о том, как он работает:

http://www.defiantjs.com/#xpath_evaluator

В отличие от JSONPath, "defiant.js" обеспечивает полномасштабную поддержку синтаксиса запроса - XPath на структурах JSON.

Исходный код defiant.js можно найти здесь:
https://github.com/hbi99/defiant.js

Ответ 12

Если вы похожи на меня, и вы просто хотите сделать поиск на основе пути, но не заботитесь о реальном XPath, lodash _.get() может работать. Пример из lodash docs:

var object = { 'a': [{ 'b': { 'c': 3 } }] };

_.get(object, 'a[0].b.c');
// → 3

_.get(object, ['a', '0', 'b', 'c']);
// → 3

_.get(object, 'a.b.c', 'default');
// → 'default'