Parsing XML with Node.js Streams Part II
In my previous post Processing Large XML Data Feeds With Node.js I gave an example of calling a SOAP webservice then writing the response XML to file. I then used the xml-stream module to parse through the xml and create a CSV/TSV file. At the time I originally tried streaming directly from the http request to xml-stream but was getting an error.
I have been going through the stream-adventure workshop from NodeSchool.io. I recomend it as a great introduction into using streams in Node.js. I feel I now have a better understanding of streams in Node.js. I thought I would take another crack at piping the http response directly to xml-stream. As it turns out it was much simpler than I thought. Since the the request module itself returns a node stream, all I had to do was pass it into the xml-stream module. It worked great and was much faster than my previous program. See the full example below.
var request = require('request');
var XmlStream = require('xml-stream');
var fs = require("fs");
console.log("Sending Request...");
var fields = ['ID','FirstName','LastName','Address','City','State'];
var options = {
method: 'POST',
url: 'https://www.yourserver.com/webservice/endpoint,
headers: {
'Content-Type': 'text/xml',
'SOAPAction': 'https://www.yourserver.com/GetSomeData',
'Content-Length': Buffer.byteLength(soap),
'charset': 'utf-8'
},
body: 'Put your SOAP Request XML here'
};
var xml = new XmlStream(request(options));
var writeStream = fs.createWriteStream('./data.txt');
writeStream.write(fields.join("\t") + "\n");
xml.on('endElement: GetSomeDataResult', function(item) {
var line = [];
fields.forEach(function(field) {
line.push(item[field]);
});
writeStream.write(line.join("\t") + "\n");
});
xml.on("end", function() {
writeStream.end();
console.log("finished");
});