[javascript] десериализовать хитрый JSON

kill-still

есть строка, где лежит что-нибудь вроде:
{ "menu": "{menu.items}",
"menu.items[*]": function(x){
return x ? "id=\""+x.id+"\"" : "";} }

как её десереализовать в JSON средствами яваскрипта?

artimon

Это не JSON.
Это похоже на какой-то «шаблонизатор» JSON-а и нужно знать как его применять.

kill-still

Вообще это JSONT (аналог XSLT)
Нарисовал вот страничку, чтобы его потестировать:
<!DOCTYPE html>
<html>

<head>
<script type="text/javascript" src="../lib/jsont.js"></script>
<script language=JavaScript>
transform = function() {
var source = JSON.parse(document.getElementById("source").value);
var rule = JSON.parse(document.getElementById("rule").value);
document.getElementById("result").value = JSON.stringify(jsonT(source, rule));
}
</script>
</head>

<body>
<textarea id = "source" cols = 120 rows = 10></textarea>
<textarea id = "rule" cols = 120 rows = 10></textarea>
<br>
<input type = "button" value = " transform " onclick = javascript:transform() />
<br>
<textarea id = "result" cols = 120 rows = 10></textarea>
</body>

</html>

Если туда вставить что-нибудь из примеров:
[[1,2],[3,4]]

{ "self": "<table>\n{$}\n</table>",
"self[*]": "<tr>{$}</tr>\n",
"self[*][*]": "<td>{$}</td>" }

то нормально работает.
А если что посложнее:
{ color: "blue",
closed: true,
points: [[10,10],[20,10],[20,20],[10,20]] }

{ "self": "<svg><{closed} stroke=\"{color}\" points=\"{points}\" /></svg>",
"closed": function(x){return x ? "polygon" : "polyline";},
"points[*][*]": "{$} " }

то отваливается с "Uncaught SyntaxError: Unexpected token c "
Однако, если заменить в коде странички
    var rule = { "self": "<svg><{closed} stroke=\"{color}\" points=\"{points}\" /></svg>",
"closed": function(x){return x ? "polygon" : "polyline";},
"points[*][*]": "{$} " };

то, JSON считается валидным.

artimon

JSON это формат данных. После того, как ты его распарсил никакого JSON-а уже нет, а есть обычные JS-объекты.
JSON.parse ожидает на вход JSON как он описан в стандарте и никаких функций в нём не предусмотрено.
Если ты доверяешь входным данным, можно воспользоваться не JSON.parse, а eval-ом.

kill-still

спасибо, капитан.
З.Ы. не, eval это немного не то.
в общем я придумал такое решение: выдрать функции из строки регэкспом, запомнить ключ => функция, распарсить JSON, вставить функции, создавая их через Function

kill-still

Да, у меня косяк с терминологией, который ввёл в заблуждение. Я имел в виду как из этой строки сделать JS-объект.

kill-still

собственно вот уже готовое решение нашлось: http://www.kristofdegrave.be/2012/07/json-serialize-and-dese...
Оставить комментарий
Имя или ник:
Комментарий: