2

我有一个使用 Python 的 SimpleJSON 序列化 JSON 的网络服务,以及一个使用 Google 的 Visualization API的 javascript/ 客户端。当我尝试使用 Google 数据表的查询方法读取 JSON 响应时,我收到“无效标签”错误。

我注意到 Google 电子表格输出 JSON,对象键周围没有引号。我尝试在没有引号的情况下阅读 JSON 并且有效。我想知道将 SimpleJSON 输出读入 Google 数据表的最佳方法是什么

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

我可以使用正则表达式来删除引号,但这似乎很草率。我尝试过的 javascript JSON 解析库不会在对象键周围没有引号的情况下以 JSON 语法读取。

这是一些很好的背景阅读:围绕对象键的引号:

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

4

3 回答 3

3

您确定 Google API 需要 JSON 吗?根据我的经验,Google 的 API 往往不会以您所描述的方式被大量破坏——可能是他们实际上期望一种仅类似于 JSON 的不同格式。


进一步探索揭示了以 Google 期望的格式检索数据的说明:

例如,要从 Google 电子表格中获取 dataSourceUrl,请执行以下操作:

  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
于 2008-10-07T00:19:43.030 回答
1

“无效标签”错误通常是由于 JSON 字符串上的盲目 eval(),导致属性名称被误认为标签(因为它们具有相同的语法 - “foo:”)。

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

快速的补救措施是确保您的 JSON 字符串有括号括住花括号:

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

尝试将您的 JSON 字符串括在括号中,以查看“无效标签”错误是否消失。

于 2008-10-07T00:34:57.477 回答
0

事实证明:mod:json也会阻塞单引号中的字符串。不过,这将解决问题:

在 python 中将 JavaScript 对象解析为 JSON:

解决方案:

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

编辑:(审查边缘案例)

因此有人提出,建议的解决方案不能处理所有情况,特别是类似的情况

例如 {foo:"a sentence: right here!"} 将更改为 {"foo":"a "sentence": right here!"}
– Jason S 4 月 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

从:

{名称:'查克',
      描述:“查克诺里斯笑话分配器。”,
      'dist-tags':{最新:'0.0.3'},
      版本:'0.0.3',
      维护者:'qard',
      时间:{'0.0.3':'2011-08-19T22:00:54.744Z'},
      作者:“斯蒂芬·贝朗格”,
      存储库:
           {类型:'git',
             网址:'git://github.com/qard/chuck.git'},
          版本:'0.0.3',
          依赖项:{ 'coffee-script': '>= 1.1.1' },
          关键词:
               ['查克',
                 '诺里斯',
                 “笑话”,
                 '有趣的',
                 '乐趣' ],
              bin: { 夹头: './bin/chuck' },
              主要:'索引',
              引擎:{节点:'>= 0.4.1 < 0.5.0'},
              devDependencies:{},
              分布:
                   { shasum: '3af700056794400218f99b7da1170a4343f355ec',
                     压缩包:' http ://registry.npmjs.org/chuck/-/chuck-0.0.3.tgz '},
                  脚本:{},
                  目录:{},
                  可选依赖项:{} }

到:

{u'author': u'Stephen Belanger',
     u'bin': {u'chuck': u'./bin/chuck'},
     u'dependencies': {u'coffee-script': u'>= 1.1.1'},
     u'description': u'Chuck Norris 笑话分配器。',
     u'devDependencies':{},
     u'目录':{},
     u'dist': {u'shasum': u'3af700056794400218f99b7da1170a4343f355ec',
      u'tarball': u' http://registry.npmjs.org/chuck/-/chuck-0.0.3.tgz '},
     u'dist-tags': {u'latest': u'0.0.3'},
     u'engines': {u'node': u'>= 0.4.1 < 0.5.0'},
     u'keywords': [u'chuck', u'norris', u'jokes', u'funny', u'fun'],
     u'main': u'index',
     u'maintainers': u'qard',
     你'名字':你'查克',
     u'optionalDependencies': {},
     u'repository': {u'type': u'git', u'url': u'git://github.com/qard/chuck.git'},
     u'脚本':{},
     u'time': {u'0.0.3': u'2011-08-19T22:00:54.744Z'},
     u'版本':u'0.0.3',
     u'版本':u'0.0.3'}

为我工作=)

开心!

于 2012-10-19T12:01:46.643 回答