从javascript中任意复杂的JSON对象生成html

从javascript中任意复杂的JSON对象生成html,javascript,jquery,json,Javascript,Jquery,Json,这里是Javascript/jQuery新手 我的Web服务器正在将目录树的内容作为JSON对象发送。根据包含其他子目录的子目录的数量,对象可以任意嵌套。看起来是这样的: { "contents": [ { "filename": "myfile", "mtime": 123456, "size": 2345, "content": nil },

这里是Javascript/jQuery新手

我的Web服务器正在将目录树的内容作为JSON对象发送。根据包含其他子目录的子目录的数量,对象可以任意嵌套。看起来是这样的:

{
    "contents": [
        {
            "filename": "myfile",
            "mtime": 123456,
            "size": 2345,
            "content": nil
        },
        {
            "filename": "mydir",
            "mtime": 2345678,
            "size": 3456788,
            "content": [
                {...},
                {...}
            ]
        }
    ]
}
myfile是一个普通文件,因此“内容”为空。mydir是一个可能为空的目录,或包含其他文件或子目录


我想用javascript解析这个JSON,并生成内容的html ul表示。我的问题是:有没有一种简单/推荐的方法可以做到这一点

如果您使用jQuery通过ajax调用接收JSON文本,jQuery会将其反序列化为对象图。如果您以其他方式接收它并将其保存在字符串中,则可以使用进行反序列化

但是,您引用的JSON无效,特别是这一位:

"content": nil
JSON中没有
nil
关键字。您需要修复服务器,要么完全关闭密钥,要么使用
null
,或者其他方法。有效的JSON是在上定义的,您可以使用它进行方便的验证(和格式化)。一致使用
内容
内容
也可能有用;当前顶层使用
内容
,而下级条目使用
内容

一旦有了对象图,递归函数就相当简单了,循环遍历数组条目,对于可以包含嵌套内容的条目,再次调用自身来循环遍历。像这样模糊的东西():

jQuery(函数($){
显示(“加载JSON数据”);
$.ajax({
键入:“获取”,
url:“/path/to/the/data”,
数据类型:“JSON”,
成功:功能(数据){
显示(“获取数据,呈现数据”);
$(document.body).append(renderContents(data.contents));
},
错误:函数(){
显示(“发生错误”);
}
});
函数呈现内容(contents){
var指数,ul;
//为这些内容创建一个列表
ul=$(“
    ”); //填写 $.each(内容、功能(索引、条目){ 李华; //创建列表项 li=$(“
  • ”); //设置文本 li.text(entry.filename); //附加其内容的子列表(如果有) if(entry.content){ li.append(renderContents(entry.content)); } //将此项目添加到我们的列表中 ul.附加(li); }); //还它 返回ul; } 功能显示(msg){ $(“”).html(msg.appendTo(document.body); } });
使用jQuery。在jQuery
ajax
函数中,对
数据类型使用
json
,它将自动解析json并返回一个json对象。您可以使用jQuery遍历json数组中的每个函数,并使用其中的数据创建ui

$.ajax({url:'ur url',dataType:'json',success:function(result){
var dhtml="<ul>";
$.each(result.contents,function(key,value){
        dhtml+="<li><span>"+value.filename+"</span><span>"+value.mtime+"</span></li>";
  })

dhtml+="</ul>";

$(body).append(dhtml);//Will add the result to ur html body
}
})
$.ajax({url:'ururl',数据类型:'json',成功:函数(结果){
var dhtml=“
    ”; $.each(结果、内容、函数(键、值){ dhtml+=“
  • ”+value.filename+”+value.mtime+“
  • ”; }) dhtml+=“
”; $(body.append(dhtml);//将结果添加到您的html正文中 } })


循环遍历这种遍历结构的最简单方法通常是编写递归(“自调用”)函数:

// $parent is a jQuery object referring to an element 
// you what to create the tree in.
// data is your (parsed) JSON object.
function displayFileTree($parent, data) {
  if (data["contents"] && data["contents"].length) {
    var contents = data["contents"];

    // create a list element
    $list = $("<ul/>");

    // loop over the "contents"
    for (var i = 0, len = contents.length; i < len; i++) {

       // create list item, set its text and append it to the list
       $item = $("<li/>").text(contents[i].filename).appendTo($list);

       // call this function to create a sublist of the subitems
       displayFileTree($item, contents[i]);

    }

    // add list to parent
    $parent.append($list);
  }
}
/$parent是引用元素的jQuery对象
//您可以选择要在其中创建树的内容。
//数据是您的(已解析的)JSON对象。
函数displayFileTree($parent,data){
if(数据[“内容”]&数据[“内容”]长度){
变量内容=数据[“内容”];
//创建一个列表元素
$list=$(“
    ”); //在“内容”上循环 for(变量i=0,len=contents.length;i”).text(内容[i].filename).appendTo($list); //调用此函数以创建子项的子列表 displayFileTree($item,contents[i]); } //将列表添加到父级 $parent.append($list); } }
(此函数假设JSON是正确的,正如T.J.Crowder的回答所建议的,尤其是它在任何地方都使用“contents”作为键,而不是“content”。)


(编辑:在Crowder用类似的解决方案扩展他的答案之前,我就开始写这篇文章。)

你试过什么了吗?请注意,这是无效的(
“content”:nil
——JSON中没有
nil
),谢谢大家的回答。将顶级“内容”改为“内容”。正如我在下面解释的,nil实际上是空的。您需要对文件名进行HTML转义,否则,如果它(比如)有一个符号(
&
),在您将其解释为HTML时可能会造成麻烦。
@Akhil
:您可以,但它违反了关注点分离。服务器正在生成JSON输出。它可以用于各种各样的事情;以HTML显示只是一种可能性。但在演示json中,没有此类数据可以转义na?
@Akhil
:您无法预测文件名将是什么,不正确地从服务器转义文本只是一种糟糕的做法。(顺便说一句,“na”不是一个英文单词。)@T.J.Crowder如果它是文件夹中的文件列表,那么就不可能有这样的特殊字符。谢谢提醒。nil部分实际上是一个工件,因为我在编写json时查看(clojure)对象,该对象在服务器端被转换为json字符串。在实际的json中,nils被转换为null。我也按照你的建议修改了内容->内容。
// $parent is a jQuery object referring to an element 
// you what to create the tree in.
// data is your (parsed) JSON object.
function displayFileTree($parent, data) {
  if (data["contents"] && data["contents"].length) {
    var contents = data["contents"];

    // create a list element
    $list = $("<ul/>");

    // loop over the "contents"
    for (var i = 0, len = contents.length; i < len; i++) {

       // create list item, set its text and append it to the list
       $item = $("<li/>").text(contents[i].filename).appendTo($list);

       // call this function to create a sublist of the subitems
       displayFileTree($item, contents[i]);

    }

    // add list to parent
    $parent.append($list);
  }
}