jQuery - цикл $ .each через код json - PullRequest
1 голос
/ 03 декабря 2008

Из-за того, как мой серверный скрипт выводит, я получаю несколько объектов JSON. {jsonhere} {jsonhere1} {jsonhere2} {jsonhere3} и т. д. Они ничем не отделены. Если бы я делал разделение на основе} {Я бы потерял эти скобки. Так есть ли внешняя петля, которую я могу поместить в обычный цикл $ .each, чтобы эта работа работала?

Спасибо,

Ice

Ответы [ 6 ]

2 голосов
/ 03 декабря 2008

Грубый алгоритм:

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
1 голос
/ 25 апреля 2010

Следующий ответ будет правильным JSON:

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

Поскольку ваш JSON искажен, просто исправьте его на стороне сервера. Следующий код является немного более кратким, чем предложенный EndangeredMassa, и он избегает добавления запятой между скобками, заключенными в кавычки. Я не очень хорош в RegEx, чтобы понять это с помощью одного .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];
    }
}

}

Чтобы перебрать объекты JSON, используйте следующее:

$.each(eval(newstring), function() {
     //code that uses the JSON values
     alert(this.value1);
     alert(this.value2);
});
1 голос
/ 03 декабря 2008

это не JSON.

jQuery лениво интерпретирует JSON, вызывая eval () и надеясь, что там нет «реального» кода; поэтому он этого не примет. (Я думаю, вы уже знаете это).

кажется, что ваш единственный выход - это рассматривать его как текстовую строку и использовать регулярные выражения для извлечения данных.

0 голосов
/ 10 декабря 2008

Это не JSON, на стороне клиента просто исправьте свой JSON-код, и вы можете безопасно его проверить.

var jsonWrong = '{a:1}{a:2}{a:3}';
var jsonRight = jsonWrong.replace('}{', '},{');
var json = eval('('+jsonRight+')');
0 голосов
/ 04 декабря 2008

Мне удалось собрать воедино рабочий пример! Сохраните следующий текст как HTML-страницу. Похоже, хорошо работает в IE7 и FF3. Дайте мне знать, если у вас возникнут какие-либо проблемы.

(я использовал jquery, но на самом деле это совсем не нужно.)

<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 голосов
/ 03 декабря 2008

Если вы не можете гарантировать, что какие-либо строки в данных не будут содержать "} {", вы даже не сможете безопасно разбить их, не проанализировав JSON, по крайней мере, настолько, чтобы отслеживать, находитесь ли вы в строке или нет. Например, если вы просто разделили это:

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

вокруг "} {" вы получите два недопустимых объекта JSON вместо одного.

Если вы знаете, что этого никогда не произойдет, вы можете разбить фигурные скобки и добавить «}» к каждому элементу, кроме последнего, и добавить «{» к последнему элементу. Я сделал бы это, только если бы не было абсолютно никакого другого пути, потому что он действительно хрупок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...