2017-02-05 15 views
2

Предполагая, что у меня есть довольно сложный объект JSON, например, как показано ниже:Расчет JSONPath

{ 
    "firstName": "John", 
    "address": [{ 
    "streetAddress": "1 street", 
    "special": { 
     "1 a": "1 b" 
    } 
    }, { 
    "streetAddress": "2 naist street", 
    "special": { 
     "2 a": "2 b" 
    } 
    }], 
    "phoneNumbers": [{ 
    "type": "iPhone", 
    "number": "0123-4567-8888" 
    }] 
} 

Есть ли инструменты/библиотеки для расчета JSONPath в частности ключ/значение пары?

Например: JSONPath для третьей строки данных (streetAddress": "1 street") можно извлечь с помощью JSONPath $.address[0].streetAddress.

В идеале я хочу что-то вроде этого: calculateJSONPath(3) - где 3 - это третий ключ, начиная с верхней части, и эта функция вернет $.address[0].streetAddress. Я не думаю, что будет что-то, что делает именно это, но я должен начать где-то, если не с нуля.

Редактировать: Пример использования: Пользователь загружает файл JSON в мое приложение. Я разрешаю им выбирать определенные ключи, используя мой интерфейс. Представьте флажки рядом с каждым ключом. Затем пользователь может загрузить второй JSON-файл и посмотреть, есть ли ранее выбранные клавиши/значения во втором JSON.

Редакция 2: Поиск не будет работать, поскольку я хочу, чтобы выбранный пользователем ключ/значения находился в той же иерархии, что и первый JSON. Например: если пользователь выбирает "1 a": "1 b" в первом файле JSON, второй файл JSON должен иметь тот же ключ/значение в одной и той же вложенной иерархии.

+1

Что вы Прецедент и каковы ожидаемые результаты? – charlietfl

+2

** Объекты ** не требуют соблюдения порядка ключей. Таким образом, тот же вызов 'calculateJSONPath' может дать разные результаты! –

+0

@charlietfl Pls см. Редактирование. – john

ответ

2

Вот вкус того, что я сказал (отметьте в квадрате, чтобы увидеть мою точку):

var $ = { 
 
    "firstName": "John", 
 
    "address": [{ 
 
    "streetAddress": "1 street", 
 
    "special": { 
 
     "2 a": "2 a" 
 
    } 
 
    }, { 
 
    "streetAddress": "2 naist street", 
 
    "special": { 
 
     "2 a": "2 a" 
 
    } 
 
    }], 
 
    "phoneNumbers": [{ 
 
    "type": "iPhone", 
 
    "number": "0123-4567-8888" 
 
    }] 
 
}; 
 

 

 
// the recursive function that create the structure 
 
function createStructure(container, obj, path) { 
 
    for(var key in obj) { 
 
    var d = cd(key, path); 
 
    if(typeof obj[key] == "object") 
 
     createStructure(d, obj[key], path + "['" + key + "']"); 
 
    container.appendChild(d); 
 
    } 
 
} 
 

 
// of course we call the function ... 
 
createStructure(document.getElementById("preview"), $, "$"); 
 

 

 
// create a preview element (unimportant) 
 
function cd(prop, path) { 
 
    var d = document.createElement("div"); 
 
    var s = document.createElement("span"); 
 

 
    var i = document.createElement("input"); 
 
    i.setAttribute("data-path", path + "['" + prop +"']"); 
 
    i.onclick = check; 
 
    i.type = "checkbox"; 
 
    s.appendChild(i); 
 
    
 
    s.appendChild(document.createTextNode(prop)); 
 
    d.appendChild(s); 
 
    return d; 
 
} 
 

 
// the event handler (unimportant) 
 
function check(e) { 
 
    if(e.target.checked) 
 
    alert(e.target.getAttribute("data-path")); 
 
}
div { 
 
    padding: 5px; 
 
    padding-left: 25px; 
 
} 
 

 
span { 
 
    border-bottom: 1px solid black; 
 
    border-left: 1px solid black; 
 
}
<div id="preview"> 
 
    <span><input type="checkbox" data-path="$"/>$</span> 
 
</div>

+0

Это очень приятно. Благодаря! – john

+0

@john Добро пожаловать! Но имейте в виду, что это просто вкус. Возможно, вам захочется отполировать его и добавить более классные вещи. Это было просто для того, чтобы дать представление и идеи о том, как это сделать. –

+0

Абсолютно, это больше, чем я ожидал. Ура! – john

1

Ниже будет создать DOM-структуру с прилагаемым JSON. Это очень рудиментарно, и это всего лишь доказательство концепции.

Вам нужно будет построить остальную часть приложения с этого фундамента.

Каждый уровень (UL) имеет индекс и каждый элемент (LI).

//rework JSON into a structure 
 
function buildDOMFromJSON() 
 
{ 
 
    var JSONString = document.querySelector("#uploadedJSON1").value; 
 
    
 
    //you need to add a gazillion error checks 
 
    var JSONcompiled = JSON.parse(JSONString); 
 

 
    //test if array or object 
 
    var start, isObject; 
 
    if (JSONcompiled instanceof Array) 
 
    { 
 
     start = JSONcompiled; 
 
     isObject = false; 
 
    } 
 
    else //is object 
 
    { 
 
    start = Object.keys(JSONcompiled); //create an array to start 
 
    isObject = JSONcompiled; 
 
    } 
 
    
 
    loopJSONLevel(start, isObject, document.querySelector("#JSONstructure1 > ul")); 
 
} 
 

 
function loopJSONLevel(obj, isObject, level) 
 
{ 
 
    //loop the array 
 
    obj.forEach(function(element, index){ 
 
    var objectToEvaluate; 
 
    if (isObject == false) 
 
    { 
 
     objectToEvaluate = element; 
 
    } 
 
    else 
 
    { 
 
     objectToEvaluate = isObject[element]; 
 
    } 
 

 
    //create a new level 
 
    var newLevel = document.createElement("li"); 
 
    var newLevel2 = document.createElement("ul"); 
 
    if (objectToEvaluate instanceof Array) 
 
    { 
 
     //create a new level 
 
     if (element instanceof Array) 
 
     { 
 
      newLevel2.setAttribute("data-path", index); 
 
     } 
 
     else 
 
     { 
 
      newLevel2.setAttribute("data-path", element); 
 
     }  
 
     level.appendChild(newLevel2); 
 
     loopJSONLevel(objectToEvaluate, false, newLevel2); 
 
    } 
 
    else if (Object.prototype.toString.call(objectToEvaluate) == "[object Object]") 
 
    { 
 
     //create a new level 
 
     if (element instanceof Array) 
 
     { 
 
      newLevel2.setAttribute("data-path", index); 
 
     } 
 
     else 
 
     { 
 
      newLevel2.setAttribute("data-path", element); 
 
     } 
 
     newLevel2.setAttribute("data-path", index); 
 
     level.appendChild(newLevel2); 
 
     loopJSONLevel(Object.keys(objectToEvaluate), objectToEvaluate, newLevel2); 
 
    } 
 
    else 
 
    { 
 
     //draw the value 
 
     level.appendChild(newLevel); 
 
     newLevel.textContent = objectToEvaluate; 
 
     newLevel.setAttribute("data-path", element); 
 
    } 
 
    
 
    
 
    }); 
 
} 
 
buildDOMFromJSON()
<textarea id="uploadedJSON1"> 
 
    [{ 
 
    "firstName": "John", 
 
    "address": [{ 
 
    "streetAddress": "1 street", 
 
    "special": { 
 
     "1 a": "1 b" 
 
    } 
 
    }, { 
 
    "streetAddress": "2 naist street", 
 
    "special": { 
 
     "2 a": "2 b" 
 
    } 
 
    }], 
 
    "phoneNumbers": [{ 
 
    "type": "iPhone", 
 
    "number": "0123-4567-8888" 
 
    }] 
 
}] 
 
    </textarea> 
 

 
<div id="JSONstructure1"> 
 
    <ul> 
 

 
    </ul> 
 
    </div>