最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Display JSONYAML hierarchy as a tree in HTML? - Stack Overflow

programmeradmin3浏览0评论

I have YAML data that looks sort of like this, but ~150k of it:

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

...or the same thing in JSON:

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

I want to present this content in an expandable JavaScripty HTML tree view (examples: 1, 2) to make it easier to explore. How do I do this?

I guess what I really want to figure out is how to take this YAML/JSON data, and automatically display it as a tree (with hash keys sorted alphabetically). So far, I've been tussling with YUI's tree view, but it doesn't accept straight JSON, and my feeble attempts to massage the data into something useful don't seem to be working.

Thanks for any help.

I have YAML data that looks sort of like this, but ~150k of it:

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

...or the same thing in JSON:

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

I want to present this content in an expandable JavaScripty HTML tree view (examples: 1, 2) to make it easier to explore. How do I do this?

I guess what I really want to figure out is how to take this YAML/JSON data, and automatically display it as a tree (with hash keys sorted alphabetically). So far, I've been tussling with YUI's tree view, but it doesn't accept straight JSON, and my feeble attempts to massage the data into something useful don't seem to be working.

Thanks for any help.

Share Improve this question edited Oct 28, 2008 at 20:28 Anirvan asked Oct 28, 2008 at 19:51 AnirvanAnirvan 6,3545 gold badges41 silver badges53 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 9

You can convert your JSON data to nicely nested DIVs with this. I haven't tested it with a wide number 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;
}

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

We're starting off with this:

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

Use regexps (in this case, in Perl) to remove the starting ---, and put hyphens before 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 a Markdown processor:

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

And you get an HTML list -- clean, semantic, backwards-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 enhance existing lists, so we wrap it all up:

<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 this all works out to about 5 lines of code (turn YAML into Markdown, turn Markdown into an HTML list, and place that HTML list inside a template HTML file. The generated HTML's progressively-enhanced / degradable, since it's fully viewable on non-JavaScript browsers as a plain old list.

Version 2.6 of YUI's TreeView now does take a JavaScript object but not in this format and won't sort it automatically. You would have to use YUI's JSON utility to convert it to an actual JavaScript which you will have to traverse. Your sample will have to be converted to something like this:

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

I've probably missing some comma or something. Your incoming data might 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.

发布评论

评论列表(0)

  1. 暂无评论