4

How to parse multilevel json ?

Json format (n-level deep) :

    [
      {
        "attr" : {
        "id" : "97987"
      },
      "children" : [
            {
              "attr" : {
              "id" : "97988"
            },
            "children" : [
                  {
                    "attr" : {
                    "id" : "97992"
                  },
                  "data" : "tag5"
              }],
            "data" : "tag2"
        },
        {
          "attr" : {
              "id" : "97993"
          },
          "data" : "tag6"
        }
      ],
    "data" : "tag1"
  },
  {
    "attr" : {
        "id" : "97989",
    },
    "children" : [
          {
            "attr" : {
              "id" : "97990"
            },
            "data" : "tag4"
          }],
    "data" : "tag3"
  }
]

for eg. I want to read every children "id".
I have tried $.each but that allows me to parse fixed number of levels.

Ashwin
  • 12,081
  • 22
  • 83
  • 117
  • 2
    A note to the terminology: JSON is a dataexchange format just like XML which has the advantage that it can be parsed very easily, because it uses the same notation like JS Objects - hence the name JavaScript Object Notation. JSON is always a string - the thing you are working with is a Javascript Object (the already parsed JSON). (At least I assume this, because you cannot use `$.each` on a json string - you needed to *parse* it first with `JSON.parse(jsonString)`.) – Christoph Feb 18 '13 at 09:02

2 Answers2

7

You need to use recursion.

function get_all_ids(data) {
    var result = [];

    $(data).each(function (i, element) {
        result.push(element.attr.id);

        if (element.children && element.children.length > 0) {
            var ids = get_all_ids(element.children);

            result = result.concat(ids); // or $.merge(result, ids);
        }
    });

    return result;
}
sigod
  • 3,514
  • 2
  • 21
  • 44
2

Using $.each() and check object or array for each object.

  1. if object index is "id", push id object into result array
  2. if object is array or object, call recursively.
  3. if not, just return.

Here's some code. Working code is at http://jsfiddle.net/cwdoh/KKFCZ/

function getAll( input, target ) {
    var result = [];

    function parseData( input, target ) {
        $.each( input, function ( index, obj ) {
            if ( index == target ) {
                result.push( obj );
            }
            else {
                switch ( $.type( obj ).toLowerCase() ) {
                case "object":
                case "array":
                    parseData( obj, target );
                    break;
                }
            }
        } );
    }

    parseData( data, "id" );

    return result;
}
cwdoh
  • 196
  • 10