How to use $ .each loop through json code in JQuery

Thanks to the way my server-side script is outputting, I am getting multiple JSON objects. {jsonhere}{jsonhere1}{jsonhere2}{jsonhere3} etc..

They are not separated by anything. If I was doing division based on }{

I would lose those brackets. So is there an external loop I can put on top of a normal loop $.each

to make this work?

Thank,

ice

+1


source to share


6 answers


Rough algorithm:



Define a stack
Define an array
LOOP on each character in the string
    IF the top item of the stack is a single or double quote THEN
        LOOP through each character until you find a matching single or double quote, then pop it from the stack.
    ELSE
        IF "{", push onto the stack
        IF "}" THEN
            pop a "{" from the stack if it is on top    
            IF the stack is empty THEN //we just finished a full json object
                Throw this json object into an array for later consumption
            END IF
        END IF
        IF single-quote, push onto the stack
        IF double-quote, push onto the stack 
    END IF
END LOOP

      

+2


source


it is not JSON.

jQuery interprets JSON in a lazy way, calling eval () and hoping there is no "real" code there; therefore he will not agree with it. (I think you already know this).



Your only way out seems to be to treat it as a text string and use regular expressions to retrieve the data.

+1


source


Below would be a valid JSON response:

[
     {JSON},
     {JSON},
     {JSON},
     {JSON}
]

      

Since your JSON is wrong, just fix it server side. The following code is a little more concise than suggested in the book called EndangeredMassa, and it avoids adding a comma between the curly braces enclosed in quotes. I'm not that good with RegEx to get my head around a single .replace ().

var string = "{\"key\":\"val}{ue\"}{'key':'val}{ue'}{ \"asdf\" : 500 }";
var result = string.match(/('.*?')|(".*?")|(\d+)|({)|(:)|(})/g);
var newstring = "";
for (var i in result) {
    var next = parseInt(i) + 1;
    if (next <= result.length) {
        if (result[i] == "}" && result[next] == "{") {
            newstring += "},";
        }
        else {
    newstring += result[i];
    }
}

      

}

Use the following to loop through JSON objects:

$.each(eval(newstring), function() {
     //code that uses the JSON values
     alert(this.value1);
     alert(this.value2);
});

      

+1


source


If you can't guarantee that any strings in the data won't contain "} {", you can't even split it up without parsing JSON, at least enough to keep track of whether you're in a string or not. For example, if you just split this:

{"foo": "}{", "bar": 42}

      

around "} {", you should get two invalid JSON objects instead of one.

If you know this will never happen, you can strip the curly braces and add "}" to every element except the last one and add "{" to the last element. I would only do this if there was absolutely no other way, because it's really fragile.

0


source


I managed to put together a working example! Save the following text as an html page. It seems to work well in IE7 and FF3. Let me know if you have any problems with this.

(I used jquery, but it really isn't needed at all.)

<html>
<head>
    <script type="text/javascript" src="jquery-1.2.6.js"></script>
    <script type="text/javascript">

        function handleClick() {
            var jsonStrs = parse();
            var jsonObjs = [];
            for(var j=0;j<jsonStrs.length;j++) jsonObjs.push( parseJSON(jsonStrs[j]) );

            //jsonObjs now contains an array of json objects 

            document.getElementById('log').innerHTML = '';
            displayResults(jsonObjs);
        }

        function displayResults(jsonObjs) {
            for(var k=0; k<jsonObjs.length; k++) {
                ShowObjProperties(jsonObjs[k]);
            }
        }

        function ShowObjProperties(obj) {
            var property, propCollection = "";

            for(property in obj) {
                propCollection += (property + ": " + obj[property] + "<br>");
            }

            log(propCollection);
        }


        function parseJSON(str) {
            var x_result = null;
            eval('x_result = ' + str);
            return x_result;
        }

        function parse() {
            //Setup
            var out = $('#output');
            var rawinput = $('#inputtext').val();
            var input = rawinput.split('');
            var stack = [];
            stack.top = function() {
                if (this.length == 0) return null;
                return this[this.length-1];
            }
            var jsonStrs = [];

            //Main Loop
            var ch = '';
            var top = '';
            var cursor = 0;
            var i = 0;
            while (i<input.length) {
                //Current Character
                ch = input[i];

                top = stack.top(); 

                if(top == "'" || top == '"') { //Ignore the rest of the string
                    //You can add validation for possible unsafe javascript inside a string, here.

                    ch = input[++i];

                    while(ch != top) {
                        i++;
                        if(i>=input.length) {
                            alert('malformed string');
                            break;
                        }
                        ch = input[i];
                    }
                    stack.pop();

                } else {
                    //You can add validation for unsafe javascript here.

                    if(ch == ' ') {
                        i++;
                        continue; // Ignore spaces
                    }

                    if(ch == "{" || ch == "'" || ch == '"') stack.push(ch);
                    if(ch == "}") {
                        if(top=="{") {
                            stack.pop();
                        } else {
                            alert('malformed string');
                            break;
                        }

                        if(stack.length == 0) {
                            var str = rawinput.substring(cursor, i+1)
                            jsonStrs.push(str);
                            cursor = i+1;
                        }
                    }
                }

                i++;
            }

            return jsonStrs;
        }

        function log(msg) {
            document.getElementById('log').innerHTML += msg + '<br>';
        }

    </script>
</head>

<body>
    <textarea id="inputtext" rows="5" cols="40" style="overflow:auto">{foo:'bar'}</textarea><br>
    <button id="btnParse" onclick="handleClick();">Parse!</button><br /><br />

    <div id="output">
    </div>

    <b>Results:</b>
    <div id="log"></div>

</body>
</html>

      

0


source


It's not JSON, on the client side just fix your JSON code and you can "eval" it safely.

var jsonWrong = '{a:1}{a:2}{a:3}';
var jsonRight = jsonWrong.replace('}{', '},{');
var json = eval('('+jsonRight+')');

      

0


source







All Articles