Display JSON / YAML hierarchy as tree in HTML?

I have YAML data that looks something like this, but ~ 150k:

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

... or the same in JSON:

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

I want to present this content in an extensible representation of the JavaScripty HTML tree (examples: 1 , 2 ) so that it is easier to explore. How to do it?

I think I really want to understand how to take YAML / JSON data and automatically display it as a tree (with hash keys sorted alphabetically). So far, I have been talking to the YUI tree view , but it does not accept direct JSON, and my weak attempts to massage the data into something useful do not seem to work.

Thanks for any help.

+6
json javascript html yui treeview
source share
3 answers

I finally came up with a super-elegant way to do this in about 5 lines of code, based on the fact that simple YAML is very similar to Markdown .

We start with this:

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

Use regular expressions (in this case, in Perl) to remove the initial --- , and place hyphens in front of the key on each line:

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

Voila, Markdown:

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

Now just run it through the Markdown processor:

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

And you get a list of HTML - clean, semantic, backward compatible:

 <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 can improve existing listings, so we will complete everything:

 <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> 

So, all this works up to about 5 lines of code (turn YAML into Markdown, turn Markdown into an HTML list and put this HTML code into an HTML template file. The generated HTML is progressively expanded / decomposable, as it is fully viewable in non-JavaScript browsers, in the form of a simple old list.

+6
source share

You can convert JSON data into a well-nested DIV with this. I have not tested it with a lot of datasets, but it seems to work.

 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; } 
+8
source share

Version 2.6 of the YUI TreeView now executes a JavaScript object, but not in this format, and will not sort it automatically. You will need to use the YUI JSON utility to convert it to the actual JavaScript that you will need to pass. Your sample should be converted to the following:

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

I probably missed some kind of comma or something like that. Your incoming data may not be sorted, so you will have to sort each array. Then you just need to pass this object as the second argument to the TreeView constructor, and the tree should appear.

+1
source share

All Articles