如何使用 node.js 访问 json 对象的子元素

Posted

技术标签:

【中文标题】如何使用 node.js 访问 json 对象的子元素【英文标题】:How to access child element of json object using node.js 【发布时间】:2015-02-05 22:37:26 【问题描述】:

在我的 node.js 应用程序中,我从 mongodb 服务器检索值并希望将它们转换为 CSV 文件。父元素很容易从数据库中访问并显示在 CSV 文件中,但子元素不显示并且可以无法访问..

JSON 结构:

"name" : "fhj",
"age" : "23",
"gender" : "female",
"sec" : "b",
"username" : "9886666",
"language" : "HINDI",
"method" : "method2",
"timeSlot" : 
    "id" : 2,
    "fromTime" : 12,
    "toTime" : 15

我的代码:

db.users.find(function(err,values)
if(err||!values.length)
   console.log("ERROR !!!!");
else
 
   var i=1;
   str='[';
   values.forEach(function(user)
     if(i==values.length)
         str=str+' "name" : "' + user.username + '","age" : "'+ user.age +'","gender":"'+user.gender+'","sec":"'+user.sec+'","username":"'+user.username+'","language":"'+user.language+'","method":"'+user.method+'","Timeslot":"'+user.timeslot+'"';
     else
       str = str + ' "name" : "' + user.username + '","age" : "'+ user.age +'","gender":"'+user.gender+'","sec":"'+user.sec+'","username":"'+user.username+'","language":"'+user.language+'","method":"'+user.method+'","Timeslot":"'+user.timeslot+'",' +'\n';
       i++;
     
   );
   str = str.trim();
   str = str + ']';
   var obj=JSON.parse(str);
   json2csv(data: obj, fields: ['name', 'age','gender','sec','username','language','method','Timeslot'], function(err, csv) 
      if (err) 
          console.log(err);
      fs.writeFile('./files/user.csv', csv, function(err) 
         if (err) 
             throw err;
         console.log('File saved');
      );
   );
   
);

除了timeslot的子元素外,所有的值都会显示出来。 如何从数据库中访问 JSON 的子元素并在 CSV 文件中显示所有值???

【问题讨论】:

能否提供创建的user.csv文件。我遇到了与 json2csv 模块类似的问题。对于内部嵌套对象/数组,它不支持复杂结构。 @SaleemAhmed 你必须手动为嵌套的 json 创建 csv。 【参考方案1】:

访问嵌套元素的简单方法可以在following thread 的答案中找到(访问嵌套数据结构)。

嵌套数据结构是引用其他数组或对象的数组或对象,即它的值是数组或对象。可以通过连续应用点或括号符号来访问此类结构。

我们可以看到 timeSlot 是一个对象,因此我们可以使用点符号来访问它的属性。 items 属性的访问方式如下:

timeSlot.id

或者,我们可以对任何属性使用括号表示法,特别是如果名称中包含的字符会使其对点表示法的使用无效:

var item_name = timeSlot['id'];

获得所需的所有数据后,CSV 文件的创建应该非常简单:)

【讨论】:

【参考方案2】:

像下面这样试试

    db.users.find(function(err, users)
        if (err || !users.length) 
            return console.log(err || 'Users not found');

        // List of column to export to cvs
        var columns = ['name', 'age', 'gender', 'sec', 'username', 'language', 'method', 'timeSlot'];   

        var text = users.reduce(function(text, user)
            // user is object e.g. name : "fhj", age : "23", .. 
            // If user is json then `user = JSON.parse(user, columns);`

            // convert user to csv-line
            text += columns.reduce(function(line, col)
                // I'm don't know how timeSlot must be save => save as json
                line += (type user[col] == 'object') ? JSON.stringify(user[col], ['id', 'fromTime', 'toTime']) : user[col];
                line += ';';
                return line;
            , '') + '\n';

            return text;
        , '');

        fs.writeFile('./files/user.csv', text, function(err) 
            if (err) 
                throw err;

            console.log('File saved');
        );
    );

【讨论】:

【参考方案3】:

尝试使用 user.timeslot.fromTime && 为每个子元素创建一个键/值

【讨论】:

它显示错误:无法读取未定义的属性'fromTime'【参考方案4】:

试试这样。这会将 timeSlot 对象中的所有数据合并为单个字符串。您可以根据需要格式化该字符串。在 forEach 循环中添加代码。

var strToAdd = "";
for (var k in timeSlot) 
strToAdd += k + timeSlot[k] + "->";


...+"Timeslot":"'+strToAdd+'"....

希望这会有所帮助。

【讨论】:

【参考方案5】:

似乎问题在于,在您迭代变量values 的forEach 循环中,您访问的是user 的属性timeslot,而不是user 的值timeSlot。记住区分大小写很重要!

Here is a fiddle which demonstrates that changing the case of the object property in lines 24 and 25 solves the issue

在链接的示例中,我还对该对象进行了字符串化,以便可以将其写入文档并清楚地查看输出。我建议不要这样做,因为您稍后可能会遇到解析它的问题。相反,您应该通过访问该对象的属性来构造一个字符串。

无论如何,您出错的原因是原始代码中存在区分大小写的问题。我希望这有帮助。

【讨论】:

【参考方案6】:

当您读取结构化数据(此处:JSON)并希望将其转换为扁平数据(此处:csv)时,您必须决定如何执行扁平化。

换句话说 - 您的 csv 目标结构可能如下:

name, age, gender, sec, username, language, method, timeSlot_id, timeSlot_fromTime, timeSlot_toTime
"fhb","23","female","b","9886666","HINDI","method2",2,12,15

一旦您决定要以这种方式展平 timeSlot 中给出的结构,您就可以使用@Aikon Mokwai 中的注释而不使用 stringify - 使用@trolologuy 描述的数组表示法来阅读结构:

var timeSlot_id = timeSlot['id]';
var timeSlot_fromTime = timeSlot['fromTime'];
var timeSlot_toTime = timeSlot['toTime'];

随后,读取 csv 的人必须了解您将数据展平但不必解析任何结构,因为您确实提供了平面数据记录(因为 csv 最喜欢它)。

希望对你有帮助!

【讨论】:

【参考方案7】:

您好使用异步 foreach 循环来实现上述。以下是其工作原理的详细信息。

Async loop in nodejs

【讨论】:

【参考方案8】:
var json= 
"name" : "fhj",
"age" : "23",
"gender" : "female",
"sec" : "b",
"username" : "9886666",
"language" : "HINDI",
"method" : "method2",
"timeSlot" : 
    "id" : 2,
    "fromTime" : 12,
    "toTime" : 15
 
;
console.log(json.timeSlot['id']);
console.log(json.timeSlot['fromTime']);
console.log(json.timeSlot['toTime']);

享受:)

见jsfiddle

【讨论】:

以上是关于如何使用 node.js 访问 json 对象的子元素的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Node.js 中使用 JSON 对象更新 mySQL 表?

如何使用 swig node js 在变量中设置 JSON 对象?

Node.js / Express / Mongoose - 如何发送 JSON 以及对象视图?

如何通过使用 node.js 从实时 json 数据中提取特定字段来创建新的单个 json 对象

如何在 Node.js 中使用流对大型嵌套对象进行 JSON 字符串化?

使用 Node.js 解析不包含 JSON 对象的 JSON 数组