【问题标题】:Total Beginner Needs Help Parsing Complex JSON Array总初学者需要帮助解析复杂的 JSON 数组
【发布时间】:2017-01-12 05:57:17
【问题描述】:

* 使用新的、完整的 JSON 数据编辑 *

我要提前道歉,因为我是一个完全的编码新手。决定尝试一个项目的经理。

我希望有人可以帮助我编写代码 sn-p 来解析以下丑陋的 JSON 结果。它是 API 调用的结果,包含 4 条“记录”。由于格式问题,我不得不将其粘贴为 sn-p,我很抱歉。

{"url":"http://www.msasnow.org/trail-reports/pere-marquette-snowmobile-club/","result":{"extractorData":{"url":"http://www.msasnow.org/trail-reports/pere-marquette-snowmobile-club/","resourceId":"29ce67ff3db8907d01f84ad45b6b47e4","data":[{"group":[{"trailName":[{"text":"Pere Marquette Snowmobile Club Trail Report"}],"trailCondition":[{"text":"Fair"}],"reportDate":[{"text":"January 10th, 2017 @ 11:20am"}]}]}]},"pageData":{"resourceId":"29ce67ff3db8907d01f84ad45b6b47e4","statusCode":200,"timestamp":1484190106983},"timestamp":1484190107253,"sequenceNumber":0}}
{"url":"http://www.msasnow.org/trail-reports/greater-grayling-snowmobile-assoc/","result":{"extractorData":{"url":"http://www.msasnow.org/trail-reports/greater-grayling-snowmobile-assoc/","resourceId":"660750825d7a7e665acfd3a94ac3d20e","data":[{"group":[{"trailName":[{"text":"Greater Grayling Snowmobile Assoc. Trail Report"}],"trailCondition":[{"text":"Good"}],"reportDate":[{"text":"January 09th, 2017 @ 10:50am"}]}]}]},"pageData":{"resourceId":"660750825d7a7e665acfd3a94ac3d20e","statusCode":200,"timestamp":1484190108241},"timestamp":1484190108467,"sequenceNumber":1}}
{"url":"http://www.msasnow.org/trail-reports/st-helen-snowmobile-club/","result":{"extractorData":{"url":"http://www.msasnow.org/trail-reports/st-helen-snowmobile-club/","resourceId":"63ba9e57962c0103cf401021656d5231","data":[{"group":[{"trailName":[{"text":"St. Helen SnowPackers Snowmobile Club Trail Report"}],"trailCondition":[{"text":"Poor"}],"reportDate":[{"text":"January 09th, 2017 @ 5:02pm"}]}]}]},"pageData":{"resourceId":"63ba9e57962c0103cf401021656d5231","statusCode":200,"timestamp":1484190108869},"timestamp":1484190109341,"sequenceNumber":2}}
{"url":"http://www.msasnow.org/trail-reports/cadillac-winter-promotions/","result":{"extractorData":{"url":"http://www.msasnow.org/trail-reports/cadillac-winter-promotions/","resourceId":"d977860e12e8d285d5e7ea21e17bf43e","data":[{"group":[{"trailName":[{"text":"Cadillac Winter Promotions Trail Report"}],"trailCondition":[{"text":"Good"}],"reportDate":[{"text":"January 10th, 2017 @ 3:25pm"}]}]}]},"pageData":{"resourceId":"d977860e12e8d285d5e7ea21e17bf43e","statusCode":200,"timestamp":1484190110156},"timestamp":1484190110365,"sequenceNumber":3}}

我正在尝试从每条记录中提取 trailName、trailCondition 和 reportDate 值,以便可以将它们写在网页中(我已经记下了那部分)。但是由于“值”位于树上的较低节点中,并且有多个记录,我不知所措。

JSON 是由 import.io 创建的,我根本无法修改它。

我正在尝试 javascript,但我对所有选项持开放态度...适合编码新手。

感谢您的宝贵时间和仁慈……马克

【问题讨论】:

  • 使用 JSON.parse 解析一个 JSON 字符串
  • 您可能想使用jsonprettyprint.com 之类的东西,这样您就可以看到 JSON 的结构(顺便说一下,它不是“数组”)。解析后,可以使用标准的js符号来提取你需要的位

标签: javascript arrays json traversal


【解决方案1】:

这项工作并非微不足道,因为格式看起来很精细,并且使用对象和数组来表示可能是键值对的事物。一般的解决方案需要一些努力。

以下是如何显式获取 group 数组中您似乎想要的一些数据。也许您可以根据自己的需要对其进行调整。

var data = JSON.parse('{"url":"http://www.msasnow.org/trail-reports/pere-marquette-snowmobile-club/","result":{"extractorData":{"url":"http://www.msasnow.org/trail-reports/pere-marquette-snowmobile-club/","resourceId":"bb56c59af972a87e62bcba4206a05d4d","data":[{"group":[{"Trail Name":[{"text":"Pere Marquette Snowmobile Club Trail Report"}],"Trail Condition":[{"text":"Fair"}],"Report Date":[{"text":"January 10th, 2017 @ 11:20am"}]}]}]},"pageData":{"resourceId":"bb56c59af972a87e62bcba4206a05d4d","statusCode":200,"timestamp":1484143736420},"timestamp":1484143957298,"sequenceNumber":0}}');

// Get the group, which is an array
var group = data.result.extractorData.data[0].group;

// Get data from the group
group.forEach(function(group) {
  Object.keys(group).forEach(function(key) {
   console.log(key + ': ' + group[key][0].text);
  });
});

基于编辑的OP,下面会处理多条记录。要注意的部分是 datagroup 对象的数组。你的例子只有一组,所以代码只是得到data[0].group

该格式允许每个 data 数组中有多个 group 对象,因此很可能一些聪明的人将来会使用它(或者可能不会,但它很容易保护反对)。

因此,您可能应该遍历 data 数组并提取每个组,即使目前只有一个组。这意味着您还需要处理返回的结果对象数组,而不仅仅是单个对象。

// Assuming data arrives as records separated by returns
var data = '{"url":"http://www.msasnow.org/trail-reports/pere-marquette-snowmobile-club/","result":{"extractorData":{"url":"http://www.msasnow.org/trail-reports/pere-marquette-snowmobile-club/","resourceId":"29ce67ff3db8907d01f84ad45b6b47e4","data":[{"group":[{"trailName":[{"text":"Pere Marquette Snowmobile Club Trail Report"}],"trailCondition":[{"text":"Fair"}],"reportDate":[{"text":"January 10th, 2017 @ 11:20am"}]}]}]},"pageData":{"resourceId":"29ce67ff3db8907d01f84ad45b6b47e4","statusCode":200,"timestamp":1484190106983},"timestamp":1484190107253,"sequenceNumber":0}}\n' +
           '{"url":"http://www.msasnow.org/trail-reports/greater-grayling-snowmobile-assoc/","result":{"extractorData":{"url":"http://www.msasnow.org/trail-reports/greater-grayling-snowmobile-assoc/","resourceId":"660750825d7a7e665acfd3a94ac3d20e","data":[{"group":[{"trailName":[{"text":"Greater Grayling Snowmobile Assoc. Trail Report"}],"trailCondition":[{"text":"Good"}],"reportDate":[{"text":"January 09th, 2017 @ 10:50am"}]}]}]},"pageData":{"resourceId":"660750825d7a7e665acfd3a94ac3d20e","statusCode":200,"timestamp":1484190108241},"timestamp":1484190108467,"sequenceNumber":1}}\n' +
           '{"url":"http://www.msasnow.org/trail-reports/st-helen-snowmobile-club/","result":{"extractorData":{"url":"http://www.msasnow.org/trail-reports/st-helen-snowmobile-club/","resourceId":"63ba9e57962c0103cf401021656d5231","data":[{"group":[{"trailName":[{"text":"St. Helen SnowPackers Snowmobile Club Trail Report"}],"trailCondition":[{"text":"Poor"}],"reportDate":[{"text":"January 09th, 2017 @ 5:02pm"}]}]}]},"pageData":{"resourceId":"63ba9e57962c0103cf401021656d5231","statusCode":200,"timestamp":1484190108869},"timestamp":1484190109341,"sequenceNumber":2}}\n' +
           '{"url":"http://www.msasnow.org/trail-reports/cadillac-winter-promotions/","result":{"extractorData":{"url":"http://www.msasnow.org/trail-reports/cadillac-winter-promotions/","resourceId":"d977860e12e8d285d5e7ea21e17bf43e","data":[{"group":[{"trailName":[{"text":"Cadillac Winter Promotions Trail Report"}],"trailCondition":[{"text":"Good"}],"reportDate":[{"text":"January 10th, 2017 @ 3:25pm"}]}]}]},"pageData":{"resourceId":"d977860e12e8d285d5e7ea21e17bf43e","statusCode":200,"timestamp":1484190110156},"timestamp":1484190110365,"sequenceNumber":3}}';

// Function to process each record and return an object like:
// {trailName: value,
//  trailCondition: value,
//  reportDate: value}
function processRecord(record) {
  record = JSON.parse(record);
  var group = record.result.extractorData.data[0].group;
  var result = {}
  group.forEach(function(group) {
    Object.keys(group).forEach(function(key) {
      result[key] = group[key][0].text;
    });
  });
  return result;
}
              
// Split the data into records on new lines,
// Process each record and return result objects in an array
var processedData = data.split('\n').map(record => processRecord(record));


// Display results: for each record, write out each key and its value
processedData.forEach(function (record) {
  Object.keys(record).forEach(function(key) {
    console.log(key + ': ' + record[key]);
  })
});

// Which can also be written using arrow functions, but it's a bit obfuscated:
/*
processedData.forEach(record =>
  Object.keys(record).forEach(key =>
    console.log(key + ': ' + record[key])
  )
);
*/   

您也可以将结果格式化为表格,但我将由您决定。 ;-)

【讨论】:

  • RobG - 感谢您提供的代码,我能够使用我最初在帖子中使用的 JSON 让它工作。我已经使用多记录数据对其进行了更新,并且想知道应用于多个“记录”会有多困难。我假设当我从 HTTP 请求中准确调用它时,它的处理方式会有所不同。再次非常感谢!!我儿子终于对我的小项目感兴趣了。
  • 您发布的数据不是有效的 JSON,它应该看起来像一个数组文字 '[{...record...},{...record...},{...record...}]',而不是您发布的 '{...record...}{...record...}{...record...}'。上面可以重构为接受单个记录的函数,然后您可以将数据拆分为单独的记录,并一次将它们传递给函数。
猜你喜欢
  • 1970-01-01
  • 2021-04-11
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-08
  • 2020-05-02
  • 1970-01-01
相关资源
最近更新 更多