2016-05-12 3 views
3

У меня есть Java-скрипт Object, и мне нужно динамически читать, записывать и удалять значения на основе JSONPath.Доступ к свойствам объекта JScript JSON с использованием стиля XPath

Есть ли библиотека для JavaScript?

Я знаю, что есть jsonpath.js, но это только для получения значения или объекта на основе JSONPath. Пожалуйста помоги.

Пример:

Предположим, что у меня есть этот объект JavaScript

var someData = { 
    store: { 
     book: [{ 
      category: "fiction", 
      author: "Herman Melville", 
      title: "Moby Dick", 
      isbn: "0-553-21311-3", 
      price: 8.99 
     }, { 
      category: "fiction", 
      author: "some Author" 
      title: "The Lord of the Rings", 
      isbn: "0-395-19395-8", 
      price: 22.99 
     }], 
    } 
} 

и у меня есть JSONPath = $.store.book[0].author это JSONPath меняется каждый раз. , так что это JSONPath указывает на автора по имени Герман Мелвилл позволяет нам сказать, что значение, которое нужно заменить, это «имя2», как мне это сделать динамически.

и худший случай приходит сюда

Если JSONPath = $.store.book[*].author видеть, что 0 заменяется на * это означает, что он указывает на всех авторов книги массива.

Поэтому я должен иметь возможность читать и писать имя автора.

jsonpath.js выполняет функцию чтения, но не что-то еще.

Прокомментируйте, если я не понимаю.

+0

https://github.com/typicode/lowdb – MarkoCen

+0

Не могли бы вы разместить пример того, что вы хотели бы сделать этой библиотекой? –

+0

@AaronUllal Я добавил пример – kasey

ответ

1

вы можете попробовать что-то вроде https://lodash.com/docs#set

здесь пример:

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

lodash.set(object, 'a[0].b.c', 4); 
console.log(object.a[0].b.c); 
+0

Головки, если вы не используете requirejs, amd, webpack и т. Д., Тогда lodash обычно устанавливается как 'window._', поэтому пример будет' _.set (object, 'a [0] .b ,c ', 4) ' – OzBarry

+0

Какой смысл, когда вы можете просто сделать' object.a [0] .b.c = 4'? – OrangeDog

+1

@OrangeDog следует избегать многословности. Предположим, мы хотим присвоить значение объекту в объекте, но мы не уверены, что свойство уже находится в объекте? Традиционно мы можем осторожно переходить в объект примерно так: 'data.parsed = {}; data.parsed.appl = {}; data.parsed.appl.msg = message; 'вместо этого с помощью _.set вы можете просто сделать' _.set (data, 'parsed.appl.msg', message); ' –

0

l33teral может помочь, но он не использует JSONPath. Вы можете «исследовать» пути, которые могут существовать до их доступа. Раскрытие информации: Я автор.

+0

выглядит как копия и вставка lodash методы. Раскрытие информации: Я являюсь автором. –

+0

@SitianLiu спасибо за ваш вклад. _.set() и _.unset() не были добавлены до 2015/2016. Я начал свою библиотеку в 2013 году. Я сделал это, чтобы заполнить пробелы, которые я воспринимал в lodash и подчеркивании. Любая «копия и вставка» является чисто случайной. –

0

Вот possibile решение для хранения данных в формате JSON разобранного по JSONPath Я использую мощный JavaScript eval здесь:

function jsonPath(obj,expr,arg){var P={resultType:arg&&arg.resultType||"VALUE",result:[],normalize:function(e){var t=[];return e.replace(/[\['](\??\(.*?\))[\]']/g,function(e,r){return"[#"+(t.push(r)-1)+"]"}).replace(/'?\.'?|\['?/g,";").replace(/;;;|;;/g,";..;").replace(/;$|'?\]|'$/g,"").replace(/#([0-9]+)/g,function(e,r){return t[r]})},asPath:function(e){for(var t=e.split(";"),r="$",a=1,n=t.length;n>a;a++)r+=/^[0-9*]+$/.test(t[a])?"["+t[a]+"]":"['"+t[a]+"']";return r},store:function(e,t){return e&&(P.result[P.result.length]="PATH"==P.resultType?P.asPath(e):t),!!e},trace:function(e,t,r){if(e){var a=e.split(";"),n=a.shift();if(a=a.join(";"),t&&t.hasOwnProperty(n))P.trace(a,t[n],r+";"+n);else if("*"===n)P.walk(n,a,t,r,function(e,t,r,a,n){P.trace(e+";"+r,a,n)});else if(".."===n)P.trace(a,t,r),P.walk(n,a,t,r,function(e,t,r,a,n){"object"==typeof a[e]&&P.trace("..;"+r,a[e],n+";"+e)});else if(/,/.test(n))for(var l=n.split(/'?,'?/),s=0,c=l.length;c>s;s++)P.trace(l[s]+";"+a,t,r);else/^\(.*?\)$/.test(n)?P.trace(P.eval(n,t,r.substr(r.lastIndexOf(";")+1))+";"+a,t,r):/^\?\(.*?\)$/.test(n)?P.walk(n,a,t,r,function(e,t,r,a,n){P.eval(t.replace(/^\?\((.*?)\)$/,"$1"),a[e],e)&&P.trace(e+";"+r,a,n)}):/^(-?[0-9]*):(-?[0-9]*):?([0-9]*)$/.test(n)&&P.slice(n,a,t,r)}else P.store(r,t)},walk:function(e,t,r,a,n){if(r instanceof Array)for(var l=0,s=r.length;s>l;l++)l in r&&n(l,e,t,r,a);else if("object"==typeof r)for(var c in r)r.hasOwnProperty(c)&&n(c,e,t,r,a)},slice:function(e,t,r,a){if(r instanceof Array){var n=r.length,l=0,s=n,c=1;e.replace(/^(-?[0-9]*):(-?[0-9]*):?(-?[0-9]*)$/g,function(e,t,r,a){l=parseInt(t||l),s=parseInt(r||s),c=parseInt(a||c)}),l=0>l?Math.max(0,l+n):Math.min(n,l),s=0>s?Math.max(0,s+n):Math.min(n,s);for(var o=l;s>o;o+=c)P.trace(o+";"+t,r,a)}},eval:function(x,_v,_vname){try{return $&&_v&&eval(x.replace(/@/g,"_v"))}catch(e){throw new SyntaxError("jsonPath: "+e.message+": "+x.replace(/@/g,"_v").replace(/\^/g,"_a"))}}},$=obj;return expr&&obj&&("VALUE"==P.resultType||"PATH"==P.resultType)?(P.trace(P.normalize(expr).replace(/^\$;/,""),obj,"$"),P.result.length?P.result:!1):void 0} 
 

 
var console = { 
 
    log: function(s) { 
 
    s = s.replace(/\\n/, '<br/>'); 
 
    document.getElementById("console").innerHTML += s + "<br/>" 
 
    } 
 
} 
 

 
var someData = { 
 
    store: { 
 
    book: [{ 
 
     category: "fiction", 
 
     author: "Herman Melville", 
 
     title: "Moby Dick", 
 
     isbn: "0-553-21311-3", 
 
     price: 8.99 
 
    }, { 
 
     category: "fiction", 
 
     author: "some Author", 
 
     title: "The Lord of the Rings", 
 
     isbn: "0-395-19395-8", 
 
     price: 22.99 
 
    }], 
 
    } 
 
} 
 

 
jsonPathStore = function(obj,path,values) { 
 
var maps=jsonPath(obj, path,{resultType:"PATH"}) 
 
maps.map(function(item,index) { 
 
    return eval('(' + item.replace(/\$/,"obj") + '="' + values[index] +'"' + ')'); 
 
}) 
 
} 
 

 
jsonPathDelete = function(obj,path) { 
 
var maps=jsonPath(obj, path,{resultType:"PATH"}) 
 
maps.map(function(item,index) { 
 
    return eval('(' + 'delete ' + item.replace(/\$/,"obj") + ')'); 
 
}) 
 
} 
 

 
jsonPathRead = function(obj,path) { 
 
var maps=jsonPath(obj, path,{resultType:"PATH"}) 
 
return maps.map(function(item,index) { 
 
    return eval('(' + item.replace(/\$/,"obj") + ')'); 
 
}) 
 
} 
 

 
    
 
console.log("JSON "+JSON.stringify(someData, null, 2)) 
 
console.log("jsonPathRead " + JSON.stringify(jsonPathRead(someData,"store.book[*].title"), null, 2)) 
 

 
jsonPathStore(someData,"store.book[*].author", ["Loreto", "Loreto Parisi"]) 
 

 
console.log("jsonPathStore " + JSON.stringify(someData, null, 2)) 
 

 
jsonPathStore(someData,"store.book[*].title", ["JavaScript", "Ninja"]) 
 

 
jsonPathDelete(someData,"store.book[*].price") 
 

 
console.log("jsonPathDelete " + JSON.stringify(eval("(" + "someData" + ")"), null, 2))
<div id="console" />

Функция jsonPathStore принимать 3 арг, то JSON объект, строка типа xpath и массив подстановок. Функция jsonPathDelete принимает 2 аргумента, объект json и xpath как строка. Он удалит все соответствующие ключи.

Это общее решение, которое может улучшить работу с конкретными случаями.

+0

Что мы изобретаем здесь здесь? Там есть много СУХИХ решений –

+1

@SitianLiu, а мой ответ - да и нет. Есть хорошие решения, но не стиль 'xpath', такие как JSONSelect - http://jsonselect.org, а также различные решения для прохождения json, кстати здесь я решаю конкретную проблему. – loretoparisi

+1

true true. Вы можете полностью загрузить это в git. Я бы полностью назвал его как конкретную библиотеку Xpath. –