如何使用nodejs将可读stream转换为有效的JSON?

我正在尝试使用音乐会数据的ATOM提要,并将其输出到JSON以获得更好的消费。

到目前为止,我一直在使用请求来获取数据和feedparser来parsing它,它似乎正在工作,因为我想。

// data var feed = 'http://mix.chimpfeedr.com/630a0-dcshows'; var wstream = fs.createWriteStream('data.json'); var req = request(feed); var feedparser = new FeedParser({ addmeta: false }); req.on('response', function(res) { var stream = this; if (res.statusCode != 200) return this.emit('error', new Error('Bad status code')); stream.pipe(feedparser) }); feedparser.on('readable', function() { var stream = this; var item; // ... do some business work to get a `data` object wstream.write( JSON.stringify(data) + ',' ); }); 

这写了一个文件,这是一个字面上这些数据对象的连接列表:

 { object1 }, { object2 }, { etc }, 

这很酷,但我想这是包装在一个数组,我想最后一个项目之后没有逗号。 我相信我可以绕过这个方法,但是我想我错过了一个stream式方法的核心概念和实际发生的事情。

所以我的问题是:如何操作可读stream(XML)并输出有效的JSON数组?

也许你的做法的问题是,你在stream中的每个JSON元素的末尾添加逗号。 这种方法失败了,因为您无法确定是否会有更多数据从阅读stream中传出。

所以,更好的方法是在JSON元素的开始处添加逗号,但前提是您之前已经处理了至less一个元素。 对于这个问题,你可以有一个标志或一个variables来统计你已经处理的元素的数量,并根据这个variables决定你是否处理第一个元素。

如果你在第一个元素,那么你添加"["到stream,表示数组的开始,并在它之后,你将第一个元素添加到写入stream。 如果你没有处理第一个元素,那么这意味着你在第二,第三或n元素,在这种情况下,你开始添加一个逗号,然后你的元素。

最后,在读取的stream上添加一个'end'事件的监听器,这样,当你到达数据的末尾时,你会得到通知,然后你可以添加你写入stream的最后一个括号"]"并完成一个有效的json数组。

我已经创build了这个例子的简化版本,使用我的硬盘上的一些本地数据。 我很确定你可以适应你的情况。

 var FeedParser = require('feedparser'), fs = require('fs'), feed = __dirname+'/rss2sample.xml'; var ws = fs.createWriteStream('data.json'); var first = true; fs.createReadStream(feed) .on('error', function (error) { console.error(error); }) .pipe(new FeedParser()) .on('error', function (error) { console.error(error); }) .on('readable', function() { var stream = this, item; while (item = stream.read()) { if(first){ ws.write('['); first = false; } else { ws.write(','); } ws.write(JSON.stringify(item)); } }) .on('end', function(){ ws.write(']'); }); 

这会产生一个有效的json文件。