Чи є еквівалент JSON XQuery / XPath?


221

При пошуку елементів у складних масивах та хешах JSON, наприклад:

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

Чи є якась мова запитів, яку я можу використовувати, щоб знайти предмет in [0].objects where id = 3?


якщо ви не зробите його. Залиште запит на сервері та використовуйте REST, щоб отримати лише потрібні вам дані.
zzzzBov

5
+1 хороша ідея.

2
Не XPath, але я знайшов JLinq досить непоганим (що робить код для читання як in(...).where(...).select(...)): hugoware.net/Projects/jLinq .
pimvdb

4
Це засмучує те, що там багато бібліотек, але нічого не наближається до загальноприйнятого стандарту. У нас є бібліотека, яку використовують треті сторони, тому нам потрібно надати мову запитів, яка широко відома і використовується.
Девід Тілен

1
Звичайно, ви можете використовувати jsel - github.com/dragonworx/jsel - якщо у вас є змінна, dataяка містить ваш об'єкт JSON, ви б написали: jsel(data).select("//*[@id=3]")і він поверне об’єкт, що містить ключ id з 3.
Алі

Відповіді:


122

Так, це називається JSONPath . Зараз джерело на GitHub .

Він також інтегрований у DOJO .


3
Відповідь Брайана передбачає, що замість модуля jsonPath в доджо слід використовувати модуль jsonQuery.
hugomg

5
Наскільки це твердо? І я не можу знайти версію Java або C #, яка є вбивцею для нас.
Девід Тілен

2
Тут розміщений веб-сайт, що підтримує Javascript та PHP. Якщо вам потрібна реалізація Java, тут є ось такий: code.google.com/p/json-path
Маттіас Ронге

2
Слід зазначити, що JSONPath не базується на формальній семантиці XPath. JSONiq може бути кращим варіантом.
wcandillon

1
@Pararamaeleon Це чудово працює. Проект , до речі, перенесено на GitHub . Майк, можливо, захоче додати це до відповіді, оскільки люди продовжують коментувати це.
Франклін Ю

21

Я думаю, що JSONQuery є суперкомплектом JSONPath і тому замінює його в доджо . Потім також є RQL .

З документації Dojo:

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

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


4
Здається, посилання Github JSONQuery мертве. JSONSelect також має версію JavaScript.
Henrik Aasted Sørensen

19

Мені відомі й інші альтернативи

  1. Специфікація JSONiq , яка визначає два підтипи мов: ту, яка приховує XML-деталі та надає JS-подібний синтаксис, та та, що збагачує синтаксис XQuery конструкторами JSON тощо. Зорба реалізує JSONiq.
  2. Corona , яка базується на MarkLogic, надає інтерфейс REST для зберігання, керування та пошуку XML, JSON, текстового та бінарного вмісту.
  3. MarkLogic 6 і пізніші версії надають аналогічний інтерфейс REST як Corona поза коробкою.
  4. MarkLogic 8 і пізніші версії підтримують JSON як в XQuery, так і на сервері JavaScript. Ви можете застосувати на ньому XPath.

HTH.


3
Зараз існує реалізація JSONiq: Zorba 2.6 офіційно підтримує її.
Ghislain Fourny

Примітка: MarkLogic зберігає JSON в оригіналі, починаючи з версії 8, і дозволяє безпосередньо застосовувати XPath на ньому.
grtjn

18

Узагальнити деякі поточні параметри переходу / фільтрації даних 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.

(Я спочатку розмістив цю відповідь в іншій темі, але вважав, що вона також буде корисною.)


Чудовий підсумок та приклади, також через те, що згадується про натхнення, знайдене або у селекторах CSS, або у XPath.
Йохім Шуленклоппер

13

Спробуйте використовувати JSPath

JSPath - мова, орієнтована на домен (DSL), яка дозволяє орієнтуватися та знаходити дані в документах JSON. Використовуючи JSPath, ви можете вибрати елементи JSON, щоб отримати дані, які вони містять.

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

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


9

XQuery можна використовувати для запиту JSON за умови, що процесор пропонує підтримку JSON. Це простий приклад того, як BaseX можна використовувати для пошуку об’єктів з "id" = 1:

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

(6 років далі) Saxon запустить XQuery 3.1, який запитує JSON. Мій саксонський досвід - це використання файлу jar, який управляє Java. Існує модуль вузла на ім'я saxon-java, але я не впевнений, як це працює з json. І є ще одна нова річ від Saxonica під назвою Saxon-JS.
charles ross

9

Чи є якась мова запитів ...

jq визначає мовою J SON q, яка дуже схожа на JSONPath - див. https://github.com/stedolan/jq/wiki/For-JSONPath-users

... [який] я можу знайти предмет у [0] .об'єктах, де id = 3?

Я припускаю, що це означає: знайдіть усі об'єкти JSON під вказаним ключем з id == 3, незалежно від того, де об'єкт може бути. Відповідним запитом jq було б:

.[0].objects | .. | objects | select(.id==3)

де "|" є трубним оператором (як у командних оболонкових трубах), і де сегмент ".. | об'єкти" відповідає "незалежно від того, де об'єкт може бути".

Основи jq в основному очевидні або інтуїтивно зрозумілі або, принаймні, досить прості, а більшість решти легко підібрати, якщо ви взагалі знайомі з командними оболонками. Поширені питання jq мають вказівки на підручники тощо.

jq також схожий на SQL, оскільки він підтримує CRUD-операції, хоча jq-процесор ніколи не перезаписує свій вхід. jq також може обробляти потоки сутностей JSON.

Ще два критерії, які ви можете врахувати при оцінці мови запитів, орієнтованих на JSON, є:

  • чи підтримує він регулярні вирази? (jq 1.5 має всебічну підтримку регулярного виразу PCRE)
  • це Тюрінг-повний? (так)

8

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

На жаль, наразі не опубліковано в npm і вимагає встановлення вручну ...
Ендрю Мао


7

Jsel приголомшливий і базується на справжньому двигуні XPath. Це дозволяє створювати вирази XPath для пошуку будь-якого типу даних JavaScript, а не лише об’єктів (також рядків).

Ви можете створити власні схеми та відображення, щоб забезпечити повний контроль над тим, як ваші дані керуються двигуном XPath. Схема - це спосіб визначення способів визначення елементів, дітей, атрибутів та вузлів у ваших даних. Тоді ви можете створити свої власні вирази на свій смак.

З огляду на те, що у вас була dataвказана змінна, яка містила JSON з питання, ви можете використовувати jsel для написання:

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

Це поверне будь-який вузол з idатрибутом 3. Атрибут - це будь-яке примітивне (рядок, число, дата, регулярний вираз) значення в об'єкті.


6

ObjectPath - мова запитів, схожа на XPath або JSONPath, але набагато потужніша завдяки вбудованим арифметичним обчисленням, механізмам порівняння та вбудованим функціям. Дивіться синтаксис:

Знайдіть у магазині все взуття червоного кольору та ціною менше 50

$ .. взуття. * [колір "червоний" і ціна <50]


Мені подобається перший приклад на веб-сайті, і це чудово, що ObjectPath можна запускати в режимі взаємодії, подібному до оболонки, але те, що я шукаю, - це використовувати ObjectPath в сценарії Python. Чи можете ви вказати мені на приклад, який показує, як використовувати ObjectPath як бібліотеку? Я не можу знайти щось подібне на веб-сайті.
piokuc

Дивіться розділ про використання Python на github . Ми додамо це на веб-сайт - це справді важко знайти. Якщо вам потрібна додаткова допомога, ви можете опублікувати питання в групі Google .
Ела Беднарек

Дякую, Ела, приклади, додані на сторінці github, - це саме те, що було потрібно.
piokuc

4

@Naftule - за допомогою "defiant.js" можна запитувати структуру JSON з виразами XPath. Ознайомтеся з цим оцінювачем, щоб отримати уявлення про те, як він працює:

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

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

Вихідний код defiant.js можна знайти тут:
https://github.com/hbi99/defiant.js


3

JMESPath, здається, дуже популярний в ці дні (станом на 2020 рік) і вирішує ряд проблем з JSONPath. Він доступний для багатьох мов.


1

Якщо ти схожий на мене, і ти просто хочеш робити пошук на основі шляху, але небайдужий до справжнього XPath, лодаш _.get()може працювати. Приклад з Dokash Dokcs:

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'

На жаль, ця функція може повернути лише один результат, вона не підтримує отримання масиву відповідних елементів, саме там світяться інші бібліотеки.
Саймон Схід

0

Спробуйте це - https://github.com/satyapaul/jpath/blob/master/JSONDataReader.java

Це дуже проста реалізація на подібній лінії xpath для xml. Це імена як jpath.


1
Це питання позначено тегом JavaScript, але, схоже, ця бібліотека призначена для java
tripleee

У ньому також є версія Javascript - github.com/satyapaul/jpath/blob/master/jpath.js Ось його головна сторінка проекту для gitub.com/satyapaul/jpath
Satyajit
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.