Как использовать цикл $ .each через json-код в JQuery

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

Спасибо,

Лед

Как конвертировать HTML в PDF с помощью jsPDF
Как конвертировать HTML в PDF с помощью jsPDF
В этой статье мы рассмотрим, как конвертировать HTML в PDF с помощью jsPDF. Здесь мы узнаем, как конвертировать HTML в PDF с помощью javascript.
1
0
15 844
6

Ответы 6

это не JSON.

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

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

Ой! Думаю, тогда я буду кодировать серверную часть - я отказываюсь использовать регулярные выражения

Ice 03.12.2008 19:41

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

adam 03.12.2008 19:45

Привет, Адам! ха-ха - мне приходилось использовать их гораздо чаще, чтобы понять, как избегать их везде, где это возможно ;-)

Ice 03.12.2008 19:54

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

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

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

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

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

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

Мне удалось сколотить рабочий пример! Сохраните следующий текст как 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>

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

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

Это не удается в следующем примере: {foo: 'sometext', bar: 'more} {text'} {moo: 'another string'} Потому что это будет вставлять запятую в строку.

EndangeredMassa 10.12.2008 17:47

Вы сказали в вопросе, что пытались разделиться на} {, поэтому я предположил, что у вас нет} {в ваших ценностях ...

Vincent Robert 12.12.2008 21:58

Следующее будет правильным ответом 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);
});

Другие вопросы по теме