【问题标题】:Display JSON/YAML hierarchy as a tree in HTML?在 HTML 中将 JSON/YAML 层次结构显示为树?
【发布时间】:2010-09-19 15:57:53
【问题描述】:

我有看起来像这样的 YAML 数据,但其中有大约 150k:

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

...或 JSON 中的相同内容:

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

我想以可扩展的 JavaScripty HTML 树状视图(例如:12)展示此内容,以便于探索。我该怎么做?

我想我真正想弄清楚的是如何获取这些 YAML/JSON 数据,并自动将其显示为树(哈希键按字母顺序排序)。到目前为止,我一直在与 YUI's tree view 争吵,但它不接受直接的 JSON,而且我将数据转化为有用的东西的微弱尝试似乎没有奏效。

感谢您的帮助。

【问题讨论】:

    标签: javascript html json treeview yui


    【解决方案1】:

    基于简单的YAML 看起来很像Markdown 的事实,我终于用大约 5 行代码想出了一个超级优雅的方法。

    我们从这个开始:

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

    使用正则表达式(在这种情况下,在 Perl 中)删除开头的 ---,并在每行的键之前放置连字符:

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

    瞧,Markdown:

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

    现在,只需通过 Markdown 处理器运行它:

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

    你会得到一个 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 可以增强现有列表,因此我们将其全部包装起来:

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

    所以这一切只需要大约 5 行代码(将 YAML 转换为 Markdown,将 Markdown 转换为 HTML 列表,并将该 HTML 列表放入模板 HTML 文件中。生成的 HTML 是渐进增强/可降解的,因为它是完全在非 JavaScript 浏览器上可作为普通旧列表查看。

    【讨论】:

    • 这很好,但请注意,降价列表必须每个级别缩进 4 个字符才能与规范兼容。 (2 个空格缩进可以在许多渲染器中使用,但是延续和代码嵌套通常不起作用。)
    【解决方案2】:

    您可以使用它将您的 JSON 数据转换为嵌套良好的 DIV。我没有使用大量数据集对其进行测试,但它似乎有效。

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

    【讨论】:

    • 这会将列表转换为嵌套的 div,但不会将 div 转换为可展开/可折叠的列表。
    • @Anirvan 您可以查看 HTML 可展开/可折叠树 here,不需要第三方库。
    【解决方案3】:

    YUI 的 TreeView 2.6 版现在确实接受了一个 JavaScript 对象,但不是这种格式,并且不会自动对其进行排序。您必须使用 YUI 的 JSON 实用程序将其转换为您必须遍历的实际 JavaScript。您的样本必须转换为以下内容:

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

    我可能遗漏了一些逗号之类的东西。您的传入数据可能未排序,因此您必须对每个数组进行排序。然后,您只需将此对象作为第二个参数传递给 TreeView 构造函数,树就会出现。

    【讨论】:

      猜你喜欢
      • 2022-07-15
      • 1970-01-01
      • 2011-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-15
      • 2018-08-21
      相关资源
      最近更新 更多