简体   繁体   中英

Recursive traversal of unknown json object/tree and actions based on returned json

I'm using a API that returns JSON on request. This JSON has either names for next level URL's or a filename.

The problem is that code has to recognize which JSON is returned.

If JSON only has a names for next url levels then create url and get it. Then recursively get a new set of names or files, recognize and do it over. It can go as menu levels deep as required. 1 to *

If it has a filename it should get it and render it as html. (This is already solved)

Example of json

{id: 'New_url_1_level_1', id:'New_url_2_level_1', id:'New_url_3_level_1'}
//or
{id:'001200.file.ext',id:'001300.file.ext'...}

These would turn into http://my.api.call.com/New_url_1_level_1.../New_url1_level_2/ ...

The problem is that how to loop over URL's and to finally get to filename for example: http://my.api.call.com/New_url_1_level_1/New_url_1_level_2/New_url_1_level_3/001300.file.ext

My current script is:

 var json;
        var urllevel= '/First_level';
        var api = 'http://my.api.call.com';
        var re = /^\d+/g; // Regex to match filename (decide if json has filenames or urls; files always start with digits or end with extension)

        var loopApiUrl = new Array();
        var recursion = false;
        // This is the problem - how to recursively build url's based on returned data i.e. traverse a "unknown" tree
        function recursePxJson(){
                if (!recursion) {
                    loopApiUrl = [];
                }
// Get JSON
            $.get(api+urllevel+'/'+loopApiUrl.join('/'),function(data,status){

                for (var i in data) {
                    if (!re.test(data[i].id)) { //     {id: 'This_is_to_be_appended_to_url', id:'Another_appendable'}
                        recursion = true;

                        loopApiUrl.push(data[i].id);
                            recursePxJson();

                        }
                        else { //    {id:'001200.file.ext',id:'001300.file.ext'}

                        load(api+urllevel+'/'+loopApiUrl.join('/')+'/'+data[i].id);
                        recursion = false;

                        }
                }

            });    
            //loadDBS(param);
        }

            // Load renderable JSON - ALREADY SOLVED
            function load(param){
            $.get(param, function(data, status){
                json = JSON.stringify(data);
                var title = data.title.split(':');
                html = '<h2>'+title[0]+'</h2>';
                html += '<h3>'+title[1]+'</h3>';
                html += '<h5>Values:</h5>';

                for (var i=0; i<data.variables.length; i++) {
                    html += '<b>'+data.variables[i].text+': </b>';
                    varlen  = data.variables[i].valueTexts.length;
                    if (varlen > 6) {
                        html += '<i>'+data.variables[i].valueTexts[0]+', '+data.variables[i].valueTexts[1]+', '+data.variables[i].valueTexts[2]+' . . . '+data.variables[i].valueTexts[varlen-3]+', '+data.variables[i].valueTexts[varlen-2]+', '+data.variables[i].valueTexts[varlen-1]+'</i>'+'<b> (yhteens&auml; '+varlen+' arvoa)</b>';
                    } else {
                        html += '<i>'+data.variables[i].valueTexts.join(',')+'</i>';
                   }
                    html += '<br/>';

                }

                $(html+'<br>').appendTo($('#tab2'));
            });
            }

EDIT: At the moment it seems like it is does each for loop before it begins another. Therefore it starts one in loop and if another is instatiated it won't be run before the fist one is done.

Main loop Internal Loop 1 Internal Loop 2 <- Isn't this the one that should done first?

  1. Handle your loopApiUrl variable as a parameter for your function recursePxJson() .

  2. Get rid of the useless recursion boolean.


You may find it easier to ditch jQuery and make use of a plain old XMLHTTPRequest. Your code will be slightly longer but you'll gain a better control of what your doing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM