3

I'm new working with JSON and the getJSON function etc and I'm trying to get data from a JSON that goes down several levels and can have multiple children. At the minute I can see the values I want by using .each with another .each such as:

$.each(data, function(i, value1) {
    $.each(value1, function(i, value2) {
        $.each(value2, function(i, value3) {
            $.each(value3, function(i, value4) {
                $.each(value4, function(i, value5) {
                    $.each(value5, function(i, value6) {
                        alert ("we got "+i);
                    });

The only problem is, I won't always know what is in the JSON and it could have unlimited children. So how would I go about making it dynamic as such?

Basically what I'm looking for is something to keep checking for children until it gets to the lowest level.

Also, I know the value i at the very end is the index for whatever value is in the JSON,

Is there any way to automate this also so that I could check for say, 'name' in the JSON and it would return the value of 'name'?

Here is a sample of the JSON i'm trying to work with:

[
 {
   "children": [
    {
      "children": [
       {
        "children": [
          {
            "children": [
              {
                "bucketPath": "AUDIO\\audio0.mp3",
                "id": 305,
                "modified": "2012-08-02T10:06:52",
                "name": "audio0.mp3",
                "state": "closed"
              }
RoverK
  • 43
  • 5

3 Answers3

9

Use recursion:

function recurse(name, obj) {
    if (!obj || typeof obj != "object")
        alert("found leaf '"+name+"': "+obj);
    else
        $.each(obj, recurse);
}
recurse("root", data);

EDIT: Based on your JSON, one could make it more specific:

function recurse(arr) {
   for (var i=0; i<arr.length; i++)
       for (var prop in arr[i])
           if (prop == "children") // && arr[i].children instanceof Array
               recurse(arr[i].children);
           else
               alert("we got "+prop+": "+arr[i][prop]);
}
recurse(data);
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • @pimvdb: Thanks. I knew there was a reason why i initially wanted to use `Object(obj)!==obj` :-) – Bergi Aug 29 '12 at 13:39
  • I think this may be exactly what i'm looking for, i'll try and encorporate that into my script and see what results I get. Thanks. – RoverK Aug 29 '12 at 13:40
  • Many thanks for this, almost there with it. Just so I understand it a bit better though, what was the point of "root" in the function call? When left in, it iterated through each letter in the word "root". – RoverK Aug 29 '12 at 14:04
  • 2
    I think he should have gone with [recursion](http://stackoverflow.com/questions/12179094/each-within-each-within-each/12179173#comment16305655_12179193) instead. – rlemon Aug 29 '12 at 14:26
  • @RoverK: The first function expects a name as the first argument, due to the way how `$.each` works. It then can log property names – Bergi Aug 29 '12 at 15:49
3

This sounds like it needs JPath or JSONPath

var name = jpath(data, '//name');
Alnitak
  • 334,560
  • 70
  • 407
  • 495
0

When JSON gets somewhat complex like this, I think dojo's JSONQuery is a good solution. It's analogous to XPath if you're familiar with that. Queries can get quite complex, but here's an example of a query to search for a property with a given name at any depth:

var results = dojox.json.query("..property_name", json_data);

There's a good article detailing the use of dojo's JSONQuery here: http://www.sitepen.com/blog/2008/07/16/jsonquery-data-querying-beyond-jsonpath/

Zach Shipley
  • 1,092
  • 6
  • 5
  • Thank you, however I'm trying my best to not use an external library on this. I'm going to have to be customising it later and would like it to remain as simple as possible. Unfortunately my knowledge doesn't stretch as far as XPath. – RoverK Aug 29 '12 at 13:42
  • That sounds fair enough to me. I'd definitely go with @Bergi 's solution, then. – Zach Shipley Aug 29 '12 at 13:46
  • @RoverK the JPath and JSONPath libraries I linked to are both very short, and make traversing structures like this completely trivial. – Alnitak Aug 29 '12 at 14:30