Правильный способ справиться с вариациями в сериализации JSON - PullRequest
2 голосов
/ 07 октября 2008

У меня есть веб-сервис, который использует SimpleJSON Python для сериализации JSON, и javascript / клиент, который использует визуализацию Google API . Когда я пытаюсь прочитать ответ JSON с помощью метода запроса таблицы данных Google, я получаю сообщение об ошибке «недопустимая метка».

Я заметил, что электронная таблица Google выводит JSON без кавычек вокруг ключей объекта. Я пытался читать в JSON без кавычек, и это работает. Мне было интересно, как лучше всего получить вывод SimpleJSON для чтения в Google, используя

query = new google.visualization.Query("http://www.myuri.com/api/").

Я мог бы использовать регулярное выражение для удаления кавычек, но это выглядит неаккуратно. Библиотеки JSON для разбора JSON, которые я пробовал, не будут читать в синтаксисе JSON без кавычек вокруг ключей объекта.

Вот хорошее фоновое чтение: цитаты вокруг ключей объекта:

http://simonwillison.net/2006/Oct/11/json/.

Ответы [ 3 ]

3 голосов
/ 07 октября 2008

Вы уверены, что Google API ожидает JSON? По моему опыту, API-интерфейсы Google, как правило, не имеют массовых нарушений, как вы описываете, - возможно, они ожидают другого формата, который просто напоминает JSON.


Дальнейшее изучение показывает инструкции для получения данных в формате, который Google ожидает:

Например, чтобы получить dataSourceUrl из таблицы Google, выполните следующее:

  1. В вашей электронной таблице выберите диапазон ячеек.
  2. Выберите «Вставить», а затем «Гаджет» из меню.
  3. Откройте меню гаджета, нажав на верхний правый селектор.
  4. Выберите пункт меню «Получить URL источника данных».

Я сделал это и открыл URL в моем браузере. Данные, которые он возвращал, были, конечно, не в формате JSON:

google.visualization.Query.setResponse(
{requestId:'0',status:'ok',signature:'1464883469881501252',
table:{cols: [{id:'A',label:'',type:'t',pattern:''},
{id:'B',label:'',type:'t',pattern:''}],
rows: [[{v:'a'},{v:'h'}],[{v:'b'},{v:'i'}],[{v:'c'},{v:'j'}],[{v:'d'},{v:'k'}],[{v:'e'},{v:'l'}],[{v:'f'},{v:'m'}],[{v:'g'},{v:'n'}]]}});

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

# old
return simplejson.dumps ({"requestId": 1, "status": "ok", ...})

# new
json = simplejson.dumps ({"requestId": 1, "status": "ok", ...})
return "google.visualization.Query.setResponse(%r);" % json
1 голос
/ 07 октября 2008

Ошибка «недопустимая метка» обычно возникает из-за слепого eval () в строке JSON, в результате чего имена свойств ошибочно принимают за метки (поскольку они имеют одинаковый синтаксис - «foo:»).

eval("{ foo: 42, bar: 43 }"); // Results in invalid label

Быстрое решение - убедиться, что в строке JSON есть круглые скобки, заключающие фигурные скобки:

eval("({ foo: 42, bar: 43 })"); // Works

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

0 голосов
/ 19 октября 2012

Как оказалось, : mod: json также захлебывается строками в одинарных кавычках. Это все уладит, хотя:

Разобрать объект JavaScript как JSON в python:

Решение:

>>> from re import sub
>>> import json
>>> js = "{ a: 'a' }"
>>> json.loads(sub("'", '"', sub('\s(\w+):', r' "\1":', js)))
{u'a': u'a'}

Редактировать: (обзор крайних случаев)

Таким образом, было выдвинуто предположение, что предлагаемое решение не справится со всеми случаями и, в частности, с чем-то вроде

например. {foo: "предложение: прямо здесь!"} будет изменено на {"foo": "a" предложение ": прямо здесь!"}
- Джейсон С. 12 апреля в 18: 03

Чтобы решить эту проблему, нам просто нужно убедиться, что мы на самом деле работаем с ключом, а не просто с двоеточием в строке, поэтому мы немного заглянем за магию, чтобы намекнуть на запятую (,) или фигурную скобку ({ ) наличие, чтобы убедиться, что это правильно, например:

двоеточие в строке:

>>> js = "{foo: 'a sentence: right here!'}"
>>> json.loads(sub("'", '"', sub('(?<={|,)\s*(\w+):', r' "\1":', js)))
{u'foo': u'a sentence: right here!'}

Что, конечно, то же самое, что и делать:

>>> js = "{foo: 'a sentence: right here!'}"
>>> json.loads(sub('(?<={|,)\s*(\w+):', r' "\1":', js).replace("'",'"'))
{u'foo': u'a sentence: right here!'} 

Но потом я указал, что это не единственный недостаток, потому что насчет цитат:

Если нас также волнуют экранированные кавычки, нам нужно будет немного конкретнее определить, что представляет собой строка. Первая кавычка будет следовать либо за фигурной скобкой ({), либо за пробелом (\ s), либо за двоеточием (:), а последняя соответствующая кавычка будет стоять перед запятой (,) или закрывающей фигурной скобкой (}), тогда мы можем рассмотреть все между ними как часть одной строки, например так:

дополнительные кавычки в строке:

>>> js = "{foo: 'a sentence: it\'s right here!'}"
>>> json.loads(
...     sub("(?<=\s|{|:)'(.*?)'(?=,|})", 
...         r'"\1"', 
...         sub('(?<={|,)\s*(\w+):', r' "\1":', js))
...     )
{u'foo': u"a sentence: it's right here!"}

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

Или, может быть, для чего-то более сложного, примера из реального мира, возвращаемого npm view:

От:

Кому:

у меня работает =)

NJoy!

...