JSONPath или другая XPath-подобная утилита для JSON / Javascript; или JQuery JSON

Я смотрел на JSONPath, и, хотя он кажется довольно неплохим, мне интересно, работал ли кто-нибудь с ним и может ли прокомментировать его удобство использования или может порекомендовать альтернативы? Что было бы действительно, так это если бы существовал плагин для JQuery, который делал бы что-то подобное. Я искал плагины и пришел с пустыми руками. В любом случае, прежде чем я потрачу время на знакомство с JSONPath (в котором есть некоторые аспекты, которые мне не интересны), или прежде, чем я изобрету колеса, я подумал, что посмотрю, есть ли у кого-нибудь угол по этому поводу ...

Чтобы дать вам представление о том, что я имею в виду, представьте себе этот объект Javascript:

var Characters=[
        {
            id: "CuriousGeorge",
            species:"Monkey",
            mood: "curious",
            appendage: [
                { 
                    type: "hand",
                    side: "left",
                    holding: [ 
                        { id: "Banana" } 
                    ]
                },
                { 
                    type: "hand",
                    side: "right",
                    holding: []
                }, 
                { 
                    type: "foot",
                    side: "left",
                    holding: []
                },
                { 
                    type: "foot",
                    side: "right",
                    holding: [ 
                        { id: "YellowHat" },
                        { id: "Keys" }
                    ]
                }
            ]
        },
        {
            id: "ManInYellowHat",
            species: "Human",
            mood: "angry",
            //...ok, you get it...
        }
    ]

Разве не было бы здорово добраться до некоторых из более глубоких объектов с помощью чего-то вроде селекторов JQuery?

var banana=SomeUtility("Characters holding #Banana").get(0);
var leftHands=SomeUtility("Characters appendage[type=hand][side=left]").get();

(Это может претендовать на самый интересный пример кода в мире, но мои дети только что это смотрели. И я не могу использовать реальный пример из-за NDA ...)

... И, чтобы было интереснее, если бы я создал такую ​​вещь, использовал бы кто-нибудь?


person jwl    schedule 13.05.2009    source источник
comment
Кажется целесообразным добавить тег [json].   -  person Tomalak    schedule 13.05.2009
comment
Интересный вопрос. Эквивалент XPath для JSON был бы отличным вариантом, хотя реализации, на которые я смотрел (JSONPath и dojox.json.query), похоже, по какой-то непонятной мне причине используют собственный синтаксис.   -  person Tomalak    schedule 13.05.2009
comment
Dojo jsonquery интересен, но да, синтаксис откровенно странный и пытается сделать намного больше, чем я хочу (и, следовательно, загромождает вещи). Но мне стоит взглянуть на это повнимательнее. Я всегда держусь подальше от додзё просто потому, что оно кажется слишком изощренным / сложным - слишком много, чтобы научиться делать что-то простое. Это просто мое личное впечатление   -  person jwl    schedule 14.05.2009


Ответы (8)


Ознакомьтесь с JSON Select - CSS-подобными селекторами для JSON.

person orad    schedule 13.12.2011
comment
ссылка указывает на неправильный веб-сайт. Это должен быть jsonselect.com? - person user152468; 22.06.2017
comment
@ user152468 Он больше не доступен на jsonselect.org. Я обновил ссылку, чтобы перейти на его репозиторий GitHub. - person orad; 28.06.2017

Однозначно была бы полезная утилита.

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

Я бы предложил что-то вроде

var banana = object.function(jsonObect, "holding #Banana");
var leftHands = object.function(jsonObject, "appendage[type=hand][side=left]");

вместо ваших примеров использования.

Я не уверен, как предстоящая встроенная поддержка json повлияет на это ...

person cofiem    schedule 14.05.2009
comment
Да, передача объекта будет иметь смысл. Вчера вечером я немного поработал над этим, и меня обнадеживают возможности ... и другие возможности появятся в будущем! - person jwl; 14.05.2009
comment
Пожалуйста, ознакомьтесь с моим ответом, я создал прототип - person jwl; 17.05.2009

Хорошо, я создал для этого прототип, доступный здесь: http://code.google.com/p/jfunk/

Он уже оказался полезным для меня, так что я, вероятно, буду постепенно улучшать и реорганизовать его во что-то хорошее. Но если я получу хорошие отзывы, я смогу двигаться быстрее. Я тоже был бы рад помочь.

person jwl    schedule 17.05.2009
comment
Ницца. Я только что бегло просмотрел код. конечно, понял суть идеи - могут быть некоторые возможные настройки, чтобы сделать его более эффективным, но, похоже, сейчас работает нормально. Я посмотрю на него через неделю или две, когда у меня будет еще немного времени. - person cofiem; 19.05.2009
comment
да, не было времени даже подумать об эффективности - кроме осознания того, что DOM имеет здесь некоторые реальные преимущества. но какие бы задачи это ни было полезно, возможно, не удастся эффективно реализовать каким-либо другим способом ... хотя это будет аргументом в пользу изменения дизайна данных ... да ладно, я думаю, это будет полезно - person jwl; 19.05.2009
comment
пустое репо и никаких изменений с ранней стадии прототипа? - person Qrilka; 25.11.2011
comment
@Qrilka, да, вы можете найти что-нибудь в разделе загрузок code.google.com/p / jfunk / downloads / list, но правильного репо нет. этот проект действительно не был интересен, и моя собственная потребность в нем отпала, так что ... Я бросил его. Если вы думаете, что это хорошая идея, я бы не отказался ее передать. Хотя я возился с node.js и могу решить, что могу как-то использовать это в конце концов, в зависимости от того, как я создаю некоторые структуры данных ... - person jwl; 29.11.2011

Попробуйте использовать JSPath - https://github.com/dfilatov/jspath.

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

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

person dfilatov    schedule 27.11.2012

Dojo dojo.getObject имеет средство, которое свободно работает, как это, где вы можете указать путь вроде «a.b.c» к свойству, которое хотите получить.

Проверить это:

http://api.dojotoolkit.org/jsdoc/1.3/dojo.getObject

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

Что касается использования, я закодировал селекторный язык, подобный тому, который вы предлагаете, но для клиента, и адресация массивов очень специфична для их конкретной объектной структуры.

Я бы определенно использовал бы такую ​​систему, если бы вы ее создали, и, возможно, даже помогли бы, если бы увидел область, в которой я мог бы помочь.

person Maciek    schedule 14.05.2009
comment
Я не нашел это интересным. Я ОПРЕДЕЛЕННО чувствую боль. Полезно для более длинных цепочек API, где вам нужно тестировать каждый объект в цепочке, поскольку мне много раз приходилось писать мусор, например var a = (b? C? D? Bcd: null: null: null ); [хотя обычно намного уродливее и включает другие условия]. Тем не менее, в целом это кажется неутешительным ... Хорошо, определенно добавлю веса созданию параллельной Jquery-подобной библиотеки для Json / JavascriptObjects, хотя будут очевидные необходимые различия, и я сомневаюсь, что производительность будет такой же хорошей ... - person jwl; 14.05.2009
comment
Пожалуйста, ознакомьтесь с моим ответом, я создал прототип - person jwl; 17.05.2009

Я только что написал клиентскую JS-библиотеку, которая делает именно это - позволяет запрашивать структуру JSON с помощью XPath.

@jlarson - с помощью defiant.js вы можете запросить свою структуру JSON следующим образом (эта библиотека расширяет глобальный объект JSON):

JSON.search( Characters, '//*[id="Banana"]' );



Этот вызов вернет массив с совпадающими узлами, И эти совпадения не будут отделены от вашего исходного объекта JSON (такое же поведение, как при работе с XML + XPath). Чтобы проиллюстрировать, что я имею в виду, вот небольшой псевдокод:

var store = {
    "book": [
        {
            "id": 1,
            "price": 8.95,
            "title": "Sayings of the Century",
            "category": "reference",
            "author": "Nigel Rees"
        },
        {
            "id": 2,
            "price": 22.99,
            "title": "The Lord of the Rings",
            "category": "fiction",
            "author": "J. R. R. Tolkien",
            "isbn": "0-395-19395-8"
         }
    ]
};

var b1 = JSON.search( store, '//book[1]' );
b1[0].isbn = '12345';

console.log( store.book[0].isbn );
// 12345

Эта библиотека пока предназначена для браузеров и клиентов, но в конце концов я планирую переписать ее для NodeJS. Ознакомьтесь с оценкой Xpath здесь; что демонстрирует функциональность. Также есть заранее написанные выражения Xpath:

http://defiantjs.com/#xpath_evaluator

Вы можете найти библиотеку на Github:
https://github.com/hbi99/defiant.js

Наконец, в defiant.js есть немного больше функций, и если вам интересно, вы, надеюсь, прочитаете об этом там (http://defiant.com)

Надеюсь, вы сочтете это полезным.

person Hakan Bilgin    schedule 02.01.2014

Похоже, появилась новая опция: jQuery-JSONPath. Кажется, это именно то, о чем вы просите.

person gregsdennis    schedule 19.08.2014

Не совсем то, что вы ищете, но попробуйте сканирование объектов. Он немного более подробный, но гораздо более мощный и поддерживает более (сложные) варианты использования. Вот пример того, как это можно использовать

// const objectScan = require('object-scan');

const Characters = [{ id: 'CuriousGeorge', species: 'Monkey', mood: 'curious', appendage: [{ type: 'hand', side: 'left', holding: [{ id: 'Banana' }] }, { type: 'hand', side: 'right', holding: [] }, { type: 'foot', side: 'left', holding: [] }, { type: 'foot', side: 'right', holding: [{ id: 'YellowHat' }, { id: 'Keys' }] }] }, { id: 'ManInYellowHat', species: 'Human', mood: 'angry' }];

console.log(objectScan(['**.holding.id'], {
  useArraySelector: false,
  abort: true,
  rtn: 'parent',
  filterFn: ({ value }) => value === 'Banana'
})(Characters));
// => { id: 'Banana' }

console.log(objectScan(['**.appendage[*]'], {
  rtn: 'value',
  filterFn: ({ value }) => value.type === 'hand' && value.side === 'left'
})(Characters));
// => [ { type: 'hand', side: 'left', holding: [ { id: 'Banana' } ] } ]
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/[email protected]"></script>

Заявление об ограничении ответственности: я являюсь автором сканирования объектов

Обязательно ознакомьтесь с файлом readme. В нем много примеров.

person vincent    schedule 17.11.2020