Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript/JSON get path to given subnode?

How would you get a JSON path to a given child node of an object?

E.g.:

var data = {
    key1: {
        children: {
            key2:'value',
            key3:'value',
            key4: { ... }
        }, 
    key5: 'value'
}

An variable with a reference to key4 is given. Now I'm looking for the absolute path:

data.key1.children.key4

Is there any way to get this done in JS?

Thank you in advance.

like image 753
user1138959 Avatar asked Jan 09 '12 15:01

user1138959


People also ask

How to get value from JSON path in JavaScript?

Use the json. path() function to query an element within JSON data. The JSON data being queried can come from the output of an activity or trigger.

Why we use JSON parse in JavaScript?

JSON.parse() A common use of JSON is to exchange data to/from a web server. When receiving data from a web server, the data is always a string. Parse the data with JSON.parse() , and the data becomes a JavaScript object.

What is. parse in JavaScript?

Parsing means analyzing and converting a program into an internal format that a runtime environment can actually run, for example the JavaScript engine inside browsers. The browser parses HTML into a DOM tree. HTML parsing involves tokenization and tree construction.

What is the use of JSONPath?

JSONPath is a query language for JSON, similar to XPath for XML. It allows you to select and extract data from a JSON document. You use a JSONPath expression to traverse the path to an element in the JSON structure.


2 Answers

This is the way i have done this.

/**
 * Converts a string path to a value that is existing in a json object.
 * 
 * @param {Object} jsonData Json data to use for searching the value.
 * @param {Object} path the path to use to find the value.
 * @returns {valueOfThePath|null}
 */
function jsonPathToValue(jsonData, path) {
    if (!(jsonData instanceof Object) || typeof (path) === "undefined") {
        throw "Not valid argument:jsonData:" + jsonData + ", path:" + path;
    }
    path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
    path = path.replace(/^\./, ''); // strip a leading dot
    var pathArray = path.split('.');
    for (var i = 0, n = pathArray.length; i < n; ++i) {
        var key = pathArray[i];
        if (key in jsonData) {
            if (jsonData[key] !== null) {
                jsonData = jsonData[key];
            } else {
                return null;
            }
        } else {
            return key;
        }
    }
    return jsonData;
}  

For testing,

var obj = {d1:{d2:"a",d3:{d4:"b",d5:{d6:"c"}}}};
jsonPathToValue(obj, "d1.d2"); // a 
jsonPathToValue(obj, "d1.d3"); // {d4: "b", d5: Object}
jsonPathToValue(obj, "d1.d3.d4"); // b
jsonPathToValue(obj, "d1.d3.d5"); // {d6: "c"}
jsonPathToValue(obj, "d1.d3.d5.d6"); // c

Hope that will help someone.

like image 103
Georgios Syngouroglou Avatar answered Sep 19 '22 16:09

Georgios Syngouroglou


So you have a variable with the value "key3", and you want to know how to access this property dynamically, based on the value of this string?

var str = "key3";
data["key1"]["children"][str];

EDIT

Wow, I can't believe I got this on the first try. There might be some bugs in it, but it works for your test case

LIVE DEMO

var x = data.key1.children.key4;

var path = "data";
function search(path, obj, target) {
    for (var k in obj) {
        if (obj.hasOwnProperty(k))
            if (obj[k] === target)
                return path + "['" + k + "']"
            else if (typeof obj[k] === "object") {
                var result = search(path + "['" + k + "']", obj[k], target);
                if (result)
                    return result;
            }
    }
    return false;
}

var path = search(path, data, x);
console.log(path); //data['key1']['children']['key4']
like image 31
Adam Rackis Avatar answered Sep 20 '22 16:09

Adam Rackis