2008-10-28 31 views
6

tengo datos YAML que se ve algo así como esto, pero ~ 150k de ella:¿Visualizar la jerarquía JSON/YAML como un árbol en HTML?

--- 
all: 
    foo: 1025 
    bar: 
    baz: 37628 
    quux: 
     a: 179 
     b: 7 

... o lo mismo en JSON:

{"all":{"bar":{"baz":"37628","quux":{"a":"179","b":"7"}},"foo":"1025"}} 

quiero presentar este contenido en una vista de árbol HTML JavaScripty expandible (ejemplos: 1, 2) para que sea más fácil de explorar. ¿Cómo hago esto?

Supongo que lo que realmente quiero averiguar es cómo tomar estos datos YAML/JSON, y mostrarlos automáticamente como un árbol (con las teclas de hash ordenadas alfabéticamente). Hasta ahora, he estado luchando con YUI's tree view, pero no acepta JSON directamente, y mis débiles intentos de dar masajes a los datos en algo útil no parecen estar funcionando.

Gracias por cualquier ayuda.

Respuesta

6

finalmente se le ocurrió una manera súper elegante de hacer esto en unos 5 líneas de código, basado en el hecho de que el simple YAML se parece mucho a Markdown.

Estamos empezando con esto:

--- 
all: 
    foo: 1025 
    bar: 
    baz: 37628 
    quux: 
     a: 179 
     b: 7 

Use expresiones regulares (en este caso, en Perl) para eliminar el --- de partida, y poner guiones antes de la tecla en cada línea:

$data =~ s/^---\n//s; 
$data =~ s/^(\s*)(\S.*)$/$1- $2/gm; 

Voila, de rebajas:

- all: 
    - foo: 1025 
    - bar: 
    - baz: 37628 
    - quux: 
     - a: 179 
     - b: 7 

Ahora, simplemente se ejecuta a través de un proces de rebajas sor:

use Text::Markdown qw(markdown); 
print markdown($data); 

Y se obtiene una lista HTML - limpio, semántica, compatible hacia atrás:

<ul> 
<li>all: 
<ul> 
<li>foo: 1025</li> 
<li>bar:</li> 
<li>baz: 37628</li> 
<li>quux: 
<ul> 
<li>a: 179</li> 
<li>b: 7</li> 
</ul></li> 
</ul></li> 
</ul> 

YUI Treeview puede mejorar las listas existentes, por lo que envolverlo todo:

<html><head> 
<!-- CSS + JS served via YUI hosting: developer.yahoo.com/yui/articles/hosting/ --> 
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/combo?2.6.0/build/treeview/assets/skins/sam/treeview.css"> 
<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.6.0/build/yahoo-dom-event/yahoo-dom-event.js&2.6.0/build/treeview/treeview-min.js"></script> 
</head><body> 
<div id="markup" class="yui-skin-sam"> 
<!-- start Markdown-generated list --> 
<ul> 
<li>all: 
<ul> 
<li>foo: 1025</li> 
<li>bar:</li> 
<li>baz: 37628</li> 
<li>quux: 
<ul> 
<li>a: 179</li> 
<li>b: 7</li> 
</ul></li> 
</ul></li> 
</ul> 
<!-- end Markdown-generated list --> 
</div> 
<script type="text/javascript"> 
var treeInit = function() { 
    var tree = new YAHOO.widget.TreeView("markup"); 
    tree.render(); 
}; 
YAHOO.util.Event.onDOMReady(treeInit); 
</script> 
</body></html> 

Así que todo esto funciona en unas 5 líneas de código (convertir YAML en Markdown, convertir Markdown en una lista HTML y colocar esa lista HTML dentro de un archivo HTML de plantilla.El HTML generado es progresivamente mejorado/degradable, ya que es completamente visible en navegadores que no son JavaScript como una simple lista anterior.

+0

Esto es agradable, pero tenga en cuenta que las listas de rebajas deben tener una sangría de 4 caracteres por nivel para que sean compatibles con las especificaciones. (2 sangría espacial funcionará en muchos procesadores, sin embargo, la continuación y el código de anidación no funcionarán regularmente). – ocodo

1

La versión 2.6 de TreeView de YUI ahora toma un objeto JavaScript pero no en este formato y no lo ordena automáticamente. Debería usar la utilidad JSON de YUI para convertirla en un JavaScript real que tendrá que atravesar. Su muestra tendrá que convertirse a algo como esto:

{label:"all", children[ 
    {label:"bar", children:[ 
     {label:"baz: 37628"}, 
     {label:"quux", children[ 
      {label:"a: 179"}, 
      {label:"b: 7"} 
     ]}, 
     {label:"foo: 1025"} 
    ]} 
]} 

Probablemente me falta algo de coma o algo así. Es posible que sus datos entrantes no estén ordenados, por lo que tendrá que ordenar cada matriz. Entonces, solo necesita pasar este objeto como el segundo argumento al constructor TreeView y debería aparecer el árbol.

8

Con esto puede convertir sus datos JSON a DIVs anidados muy bien. No lo he probado con una gran cantidad de conjuntos de datos, pero parece funcionar.

function renderJSON(obj) { 
    'use strict'; 
    var keys = [], 
     retValue = ""; 
    for (var key in obj) { 
     if (typeof obj[key] === 'object') { 
      retValue += "<div class='tree'>" + key; 
      retValue += renderJSON(obj[key]); 
      retValue += "</div>"; 
     } else { 
      retValue += "<div class='tree'>" + key + " = " + obj[key] + "</div>"; 
     } 

     keys.push(key); 
    } 
    return retValue; 
} 
+0

Esto toma la lista y la convierte en divs anidados, pero no convierte los div en una lista expandible/plegable. – Anirvan

Cuestiones relacionadas