Pregunta

Tengo un servicio web que usa SimpleJSON de Python para serializar JSON, y un javascript / cliente que usa la visualización de Google API . Cuando intento leer la respuesta JSON utilizando el método de consulta de la tabla de datos de Google, obtengo una " etiqueta inválida " error.

Noté que la hoja de cálculo de Google genera JSON sin comillas alrededor de las claves de objeto. Intenté leer en JSON sin las comillas y eso funciona. Me preguntaba cuál era la mejor manera de obtener la salida de SimpleJSON para que se pueda leer en Google datable usando

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

Podría usar una expresión regular para eliminar las comillas, pero eso parece descuidado. Las bibliotecas de análisis JSON de JavaScript que he intentado no se leerán en sintaxis JSON sin comillas en las claves de objeto.

Aquí hay una buena lectura de fondo re: citas sobre claves de objetos:

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

¿Fue útil?

Solución

¿Estás seguro de que la API de Google está esperando a JSON? En mi experiencia, las API de Google tienden a no romperse de forma masiva de la manera en que lo estás describiendo, podría ser que realmente esperan un formato diferente que simplemente se parece a JSON.


Más información sobre el tema revela instrucciones para recuperar datos en el formato que Google espera:

  

Por ejemplo, para obtener el dataSourceUrl   desde una hoja de cálculo de Google, haga el   siguiente:

     
      
  1. En tu hoja de cálculo, selecciona el rango de celdas.
  2.   
  3. Seleccione 'Insertar' y luego 'Gadget' en el menú.
  4.   
  5. Abra el menú del gadget haciendo clic en el selector de la parte superior derecha.
  6.   
  7. Seleccione la opción de menú 'Obtener URL de origen de datos'.
  8.   

Hice esto y abrí la URL en mi navegador. Los datos que estaba devolviendo ciertamente no eran 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'}]]}});

Parece que el resultado está destinado a ser ejecutado directamente por el navegador. Intente modificar su código para hacer algo como esto:

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

# new
json = simplejson.dumps ({"requestId": 1, "status": "ok", ...})
return "google.visualization.Query.setResponse(%r);" % json

Otros consejos

La " etiqueta inválida " el error generalmente se debe a un eval () ciego en la cadena JSON, lo que hace que los nombres de propiedades se confundan con etiquetas (porque tienen la misma sintaxis - " foo: ").

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

El remedio rápido es asegurarse de que la cadena JSON tenga paréntesis entre las llaves:

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

Intente encerrar su cadena JSON entre paréntesis para ver si la " etiqueta inválida " el error desaparece.

Resulta que : mod: json también se ahogaría con las cadenas entre comillas simples. Sin embargo, esto solucionará las cosas:

Analizar objeto JavaScript como JSON en python:

solución:

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

Editar: (casos límite revisados)

Por lo tanto, se mencionó que la solución sugerida no resolvería todos los casos y, específicamente, algo como

  

por ejemplo {foo: " una oración: ¡aquí mismo! "} se cambiará a {" foo " ;: " una " oración " ;, ¡aquí mismo! "}
  & # 8211; Jason S 12 de abril a las 18:03

Para resolverlo, simplemente debemos asegurarnos de que, de hecho, trabajamos con una clave y no simplemente con dos puntos en una cadena, por lo que hacemos un pequeño vistazo a la magia para sugerir una coma (,) o una llave ({ ) Presencia para asegurarnos de que la tenemos adecuada, como tal:

dos puntos en la cadena:

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

Lo que, por supuesto, es lo mismo que hacer:

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

Pero luego señalé que este no es el único defecto porque, ¿qué pasa con las citas?

Si también nos preocupan las comillas de escape, tendremos que ser un poco más específicos en cuanto a lo que constituye una cadena. La primera cita seguirá una franja ({) un espacio (\ s) o dos puntos (:), mientras que la última cita coincidirá antes de una coma (,) o una llave de cierre (}), entonces podemos considerar todo lo que está en el medio como parte de la misma cadena, así:

citas adicionales en cadena:

>>> 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!"}

Observe este espacio a medida que se revelan y resuelven más casos de borde. ¿Puedes ver a otro?

O quizás para algo más complejo, un ejemplo del mundo real como lo devuelve npm view :

Desde:

  

{ name: 'chuck',
      description: 'Chuck Norris joke dispenser.',
      'dist-tags': { latest: '0.0.3' },
      versions: '0.0.3',
      maintainers: 'qard ',
      time: { '0.0.3': '2011-08-19T22:00:54.744Z' },
      author: 'Stephen Belanger ',
      repository: 
           { type: 'git',
             url: 'git://github.com/qard/chuck.git' },
          version: '0.0.3',
          dependencies: { 'coffee-script': '>= 1.1.1' },
          keywords: 
               [ 'chuck',
                 'norris',
                 'jokes',
                 'funny',
                 'fun' ],
              bin: { chuck: './bin/chuck' },
              main: 'index',
              engines: { node: '>= 0.4.1 < 0.5.0' },
              devDependencies: {},
              dist: 
                   { shasum: '3af700056794400218f99b7da1170a4343f355ec',
                     tarball: 'http://registry.npmjs.org/chuck/-/chuck-0.0.3.tgz' },
                  scripts: {},
                  directories: {},
                  optionalDependencies: {} }

Para:

  

{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 joke dispenser.',
     u'devDependencies': {},
     u'directories': {},
     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'name': u'chuck',
     u'optionalDependencies': {},
     u'repository': {u'type': u'git', u'url': u'git://github.com/qard/chuck.git'},
     u'scripts': {},
     u'time': {u'0.0.3': u'2011-08-19T22:00:54.744Z'},
     u'version': u'0.0.3',
     u'versions': u'0.0.3'}

Funciona para mí =)

nJoy!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top