2010-10-14 17 views
5

usando el motor de aplicaciones - sí, sé todo sobre las plantillas de django y otros motores de plantillas.python: serialice un diccionario en una simple salida html

Digamos que tengo un diccionario o un objeto simple, no sé su estructura y quiero serializarlo en html.

así que si tuviera

{'data':{'id':1,'title':'home','address':{'street':'some road','city':'anycity','postal':'somepostal'}}} 

quieren que quiero es que se han convertido en una forma de HTML legible usando listas o tablas;

data: 
    id:1 
    title:home 
    address: 
      street: some road 
      city: anycity 
      postal:somepostal 

Ahora sé que puedo hacer

for key in dict.items 
print dict[key] 

pero que suele sumergirse en los valores de los niños y la lista de cada tecla, el valor de par cuando la clave/valor es un diccionario - es decir, la dirección de dict.

Es un módulo para python que es liviano/rápido y lo hará muy bien. o alguien tiene un código simple que pueda pegar y que pueda hacer esto.

Solución Todas las soluciones aquí fueron útiles. pprint es, sin duda, el medio más estable de imprimir el diccionario, aunque no llega a devolver nada cerca de html. Aunque todavía está imprimible.

terminé con esto por ahora:

def printitems(dictObj, indent=0): 
    p=[] 
    p.append('<ul>\n') 
    for k,v in dictObj.iteritems(): 
     if isinstance(v, dict): 
      p.append('<li>'+ k+ ':') 
      p.append(printitems(v)) 
      p.append('</li>') 
     else: 
      p.append('<li>'+ k+ ':'+ v+ '</li>') 
    p.append('</ul>\n') 
    return '\n'.join(p) 

Convierte la dict en listas desordenadas, que está bien por ahora. algunos CSS y quizás un pequeño ajuste deberían hacerlo legible.

Voy a recompensar la respuesta a la persona que escribió el código anterior, hice un par de pequeños cambios ya que las listas desordenadas no estaban anidando. Espero que todos estén de acuerdo en que muchas de las soluciones ofrecidas resultaron útiles, pero el código anterior representa una verdadera representación html de un diccionario, incluso si es tosco.

+1

no ser un pedante, pero no eres la serialización de su diccionario, que está imprimiéndolo (con formato HTML). – Seth

+0

@seth sí, supongo que la palabra serializar fue mal utilizada. – spidee

Respuesta

8

El ejemplo hecha por pyfunc podría ser fácilmente modificado para generar listas HTML anidados simples.

z = {'data':{'id':1,'title':'home','address':{'street':'some road','city':'anycity','postal':'somepostal'}}} 

def printItems(dictObj, indent): 
    print ' '*indent + '<ul>\n' 
    for k,v in dictObj.iteritems(): 
     if isinstance(v, dict): 
      print ' '*indent , '<li>', k, ':', '</li>' 
      printItems(v, indent+1) 
     else: 
      print ' '*indent , '<li>', k, ':', v, '</li>' 
    print ' '*indent + '</ul>\n' 

printItems(z,0) 

No terriblemente bonita, por supuesto, pero en algún lugar para comenzar tal vez. Si todo lo que quiere hacer es visualizar datos, el módulo pprint realmente es lo suficientemente bueno. Podrías usar la etiqueta "pre" en el resultado de pprint y poner eso en tu página web.

la versión pprint sería algo como esto:

import pprint 
z = {'data':{'id':1,'title':'home','address':{'street':'some road','city':'anycity','postal':'somepostal'}}} 

print '<pre>', pprint.pformat(z), '</pre>' 

Y la mirada de salida html algo como esto:

{'data': {'address': {'city': 'anycity', 
         'postal': 'somepostal', 
         'street': 'some road'}, 
      'id': 1, 
      'title': 'home'}} 

que no es que bonito, pero al menos espectáculos los datos de una manera más estructurada.

+0

+1 Esto es mucho mejor. – pyfunc

+0

lo siento pre etiqueta? ¿Cómo puedo hacer eso? ¿Me puede mostrar el código para que pprint me devuelva un resultado que está en formato de cadena y puede pasarse a mi motor de plantillas? Gracias – spidee

4
import pprint 


pprint.pprint(yourDict) 

Bueno, no HTML, pero similar a su enfoque for/print.

EDIT: o uso:

niceText = pprint.pformat(yourDict) 

esto le dará el mismo buen rendimiento con todos los guiones, etc. Ahora se puede iterar sobre las líneas y darle formato en HTML:

htmlLines = [] 
for textLine in pprint.pformat(yourDict).splitlines(): 
    htmlLines.append('<br/>%s' % textLine) # or something even nicer 
htmlText = '\n'.join(htmlLines) 
+0

Okay - quiero pasar esto a html - ¿cómo lo hago? Bueno, honestamente, ¿solo lo quiero en una cadena y puedo pasarlo a html? – spidee

+0

¿este trabajo funciona? pprint.pformat ({'data': {'count': '1', 'items': {'price': '$ 10.99', 'id': '1001', 'title': 'alquiler de palabra clave oct10'}} }) no está volviendo datos formateados? – spidee

+0

Devuelve cuatro líneas con '\ n' después de cada línea. – eumiro

1

Usted podría utilizar pretty print (pprint)

o si desea hacer un mayor procesamiento de la pantalla, entonces usted tiene que ejecutar el dict usted mismo.

Tenga en cuenta que el código es crudo y requerirá numerosos refinamientos. La solución también usa recursividad, que es mala, si la profundidad de recursión es más alta.

z = {'data':{'id':1,'title':'home','address':{'street':'some road','city':'anycity','postal':'somepostal', 'telephone':{'home':'xxx','offie':'yyy'}}}} 

def printItems(dictObj, indent): 
    it = dictObj.iteritems() 
    for k,v in it: 
     if isinstance(v, dict): 
      print ' '*indent , k, ':' 
      printItems(v, indent+1) 
     else: 
      print ' '*indent , k, ':', v 

printItems(z,0) 

de salida:

data : 
    address : 
    city : anycity 
    postal : somepostal 
    street : some road 
    telephone : 
    home : xxx 
    offie : yyy 
    id : 1 
    title : home 
+2

En lugar de 'id str (tipo (v))' == "..." use 'tipo (v) == dict' o' isinstance (v, dict) '(este último también funciona para las subclases). – detly

+0

Si la clave de la dirección tiene, por ejemplo, teléfono: {'home': 'xxx', 'offie': 'yyy'} ¿cómo va a lidiar con eso? – spidee

+0

@spidee: Edité mi respuesta anterior para incluir sus datos y se imprimirá de la misma manera. – pyfunc

2

mirada en mi aplicación:

def pretty_items(r, d, nametag="<strong>%s: </strong>", itemtag='<li>%s</li>', 
      valuetag="%s", blocktag=('<ul>', '</ul>')): 
if isinstance(d, dict): 
    r.append(blocktag[0]) 
    for k, v in d.iteritems(): 
     name = nametag % k 
     if isinstance(v, dict) or isinstance(v, list): 
      r.append(itemtag % name) 
      pretty_items(r, v) 
     else: 
      value = valuetag % v 
      r.append(itemtag % (name + value)) 
    r.append(blocktag[1]) 
elif isinstance(d, list): 
    r.append(blocktag[0]) 
    for i in d: 
     if isinstance(i, dict) or isinstance(i, list): 
      r.append(itemtag % " - ") 
      pretty_items(r, i) 
     else: 
      r.append(itemtag % i) 
    r.append(blocktag[1]) 

da salida a todos los elementos en formato HTML utilizando <ul> y <li> etiquetas. Y también es opcional cambiar las etiquetas. Y luego, solo use CSS para manejar con la sangría.

1

Necesitaba algo similar, pero también quería imprimir listas bonitas y listas dentro del diccionario. Esto es lo que ocurrió:

def format(self, obj, indent = 1): 
    if isinstance(obj, list): 
     htmls = [] 
     for k in obj: 
      htmls.append(self.format(k,indent+1)) 

     return '[<div style="margin-left: %dem">%s</div>]' % (indent, ',<br>'.join(htmls)) 

    if isinstance(obj, dict): 
     htmls = [] 
     for k,v in obj.iteritems(): 
      htmls.append("<span style='font-style: italic; color: #888'>%s</span>: %s" % (k,self.format(v,indent+1))) 

     return '{<div style="margin-left: %dem">%s</div>}' % (indent, ',<br>'.join(htmls)) 

    return str(obj) 

Entonces, si usted está utilizando aplicación web en appengine, sólo puede hacer lo siguiente:

self.response.out.write(self.format(obj)) 

Este es un ejemplo de la salida:

enter image description here

0

imaginar tenemos esto: {nombre: "a", los niños: [{nombre: "b", los niños: []}, {..}, {..}]

def ConvertDictToUlLi(): 
    jsonResult = GetSomeRecursiveDict() 

    def CreateHtml(DictItem, output): 
     output = "<li>"+DictItem["name"] if jsonResult.has_key("name") else " " 
     if len(DictItem["children"]) > 0: 
      output = output + "<ul>" 
      for item in DictItem["children"]: 
       output = output + " "+CreateHtml(item, output)+" " 
      output = output + "</ul>" 
     return output+"</li>" 
    result = "<ul class='tree'>"+CreateHtml(jsonResult, "")+"</ul>" 

return result 
0

Ninguno de los ejemplos anteriores dan buenos resultados, así que escribí dos de mis propias funciones que crean una hermosa salida html para diccionarios.

def dict_to_html(dd, level=0): 
    """ 
    Convert dict to html using basic html tags 
    """ 
    import simplejson 
    text = '' 
    for k, v in dd.iteritems(): 
     text += '<br>' + '&nbsp;'*(4*level) + '<b>%s</b>: %s' % (k, dict_to_html(v, level+1) if isinstance(v, dict) else (simplejson.dumps(v) if isinstance(v, list) else v)) 
    return text 

def dict_to_html_ul(dd, level=0): 
    """ 
    Convert dict to html using ul/li tags 
    """ 
    import simplejson 
    text = '<ul>' 
    for k, v in dd.iteritems(): 
     text += '<li><b>%s</b>: %s</li>' % (k, dict_to_html_ul(v, level+1) if isinstance(v, dict) else (simplejson.dumps(v) if isinstance(v, list) else v)) 
    text += '</ul>' 
    return text 
0

Aquí está mi versión con soporte de listas (labels son nombres detallados de teclas en el diccionario):

def render_value(value, labels): 
    if isinstance(value, (list, tuple)): 
     return render_list(value, labels) 
    elif isinstance(value, dict): 
     return render_dict(value, labels) 
    else: 
     return value 


def render_list(lst, labels): 
    items = [ 
     '<li>%s</li>' % render_value(value, labels) 
     for value in lst 
    ] 
    return '\n'.join(['\n<ul>'] + items + ['</ul>\n']) 


def render_dict(dct, labels): 
    items = [] 
    for key, value in dct.items(): 
     if not value: continue 

     key = labels.get(key, key) 
     value = render_value(value, labels) 
     items.append('<li><b>%s</b>: %s</li>' % (key, value)) 

    return '\n'.join(['\n<ul>'] + items + ['</ul>\n']) 
Cuestiones relacionadas