简体   繁体   English

将 JSON/YAML 层次结构显示为 HTML 中的树?

[英]Display JSON/YAML hierarchy as a tree in HTML?

I have YAML data that looks sort of like this, but ~150k of it:我有看起来像这样的 YAML 数据,但大约有 150k:

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

...or the same thing in JSON: ...或 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.我想在可扩展的 JavaScripty HTML 树视图(示例: 12 )中呈现此内容,以便于探索。 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).我想我真正想弄清楚的是如何获取此 YAML/JSON 数据,并自动将其显示为树(哈希键按字母顺序排序)。 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.到目前为止,我一直在与YUI 的 tree view争吵,但它不接受直接的 JSON,而且我将数据转化为有用的东西的微弱尝试似乎没有奏效。

Thanks for any help.谢谢你的帮助。

You can convert your JSON data to nicely nested DIVs with this.您可以使用此将 JSON 数据转换为很好嵌套的 DIV。 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 .基于简单的YAML看起来很像Markdown的事实,我终于想出了一个超级优雅的方法,用大约 5 行代码来做到这一点。

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:使用正则表达式(在这种情况下,在 Perl 中)删除起始--- ,并在每行的键之前放置连字符:

$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:现在,只需通过 Markdown 处理器运行它:

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

And you get an HTML list -- clean, semantic, backwards-compatible:你会得到一个 HTML 列表——干净、语义化、向后兼容:

<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: YUI Treeview可以增强现有列表,因此我们将其全部包装起来:

<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.所以这一切都适用于大约 5 行代码(将 YAML 转换为 Markdown,将 Markdown 转换为 HTML 列表,并将该 HTML 列表放在模板 HTML 文件中。生成的 HTML 逐渐增强/可降解,因为它在非-JavaScript 浏览器作为一个普通的旧列表。

Version 2.6 of YUI's TreeView now does take a JavaScript object but not in this format and won't sort it automatically. YUI 的 TreeView 2.6 版现在接受一个 JavaScript 对象,但不是这种格式,并且不会自动对其进行排序。 You would have to use YUI's JSON utility to convert it to an actual JavaScript which you will have to traverse.您必须使用 YUI 的 JSON 实用程序将其转换为您必须遍历的实际 JavaScript。 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.然后,您只需将此对象作为第二个参数传递给 TreeView 构造函数,树就会出现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM