I'm using xml-stream to read a large XML file. I'd like to:
- pipe collected elements to a stream
- optionally, to transform those elements using one or more pipes
- pipe the result to an http response
Here is xml-stream
snippet collecting required elements:
xml.on('endElement: item', function(item) {
// pipe item to stream
})
How do I build streams for step 1 and 2?
P.S. xml-stream
has only console.log
examples
UPDATE 1
Here is what I wrote so far:
stream = require('stream');
let liner = new stream.Transform( { objectMode: true } );
liner._transform = function (data, encoding, done) {
this.push(data);
console.log(data);
console.log('=======================');
done();
};
let fileStream = fs.createReadStream(fileNames[0]);
let xmlStream = new XmlStream(fileStream);
let counter = 0;
xmlStream.on('endElement: Item', function(el) {
liner.write(el);
counter += 1;
});
xmlStream.on('end', function() {
console.log(counter);
liner.end();
});
_transform
get called on every write
, however piping liner
stream to http result doesn't produce any output.
I'm using xml-stream to read a large XML file. I'd like to:
- pipe collected elements to a stream
- optionally, to transform those elements using one or more pipes
- pipe the result to an http response
Here is xml-stream
snippet collecting required elements:
xml.on('endElement: item', function(item) {
// pipe item to stream
})
How do I build streams for step 1 and 2?
P.S. xml-stream
has only console.log
examples
UPDATE 1
Here is what I wrote so far:
stream = require('stream');
let liner = new stream.Transform( { objectMode: true } );
liner._transform = function (data, encoding, done) {
this.push(data);
console.log(data);
console.log('=======================');
done();
};
let fileStream = fs.createReadStream(fileNames[0]);
let xmlStream = new XmlStream(fileStream);
let counter = 0;
xmlStream.on('endElement: Item', function(el) {
liner.write(el);
counter += 1;
});
xmlStream.on('end', function() {
console.log(counter);
liner.end();
});
_transform
get called on every write
, however piping liner
stream to http result doesn't produce any output.
2 Answers
Reset to default 6Mission acplished. The function below returns transform stream
that can be piped to any writable stream. liner._flush
is necessary only you want to add some data in the end of the stream.
P.S. A handy module (not used here) https://github./rvagg/through2
const fs = require('fs');
const stream = require('stream');
const XmlStream = require('xml-stream');
function getTransformStream() {
let liner = new stream.Transform( { objectMode: true } );
liner._transform = function (data, encoding, done) {
// have your transforms here
this.push(data);
console.log(data);
console.log('=======================');
done();
};
liner._flush = function (done) {
console.log('DONE DONE DONE DONE');
done();
};
let fileStream = fs.createReadStream('filename');
let xmlStream = new XmlStream(fileStream);
let counter = 0;
xmlStream.on('endElement: Item', function(el) {
liner.write(JSON.stringify(el));
counter += 1;
});
xmlStream.on('end', function() {
console.log(counter);
liner.end();
});
return liner;
}
Maybe you should check the example, that the library provides. If you have done that, it would be nice if you have pointed that out.
So I use Promised land for data flow and Highlandjs to create a stream from array, which has only one element- the item
.
At the end, you have stream, which you can use according to Highland docs.
var Land = require('promised-land')
var stream = fs.createReadStream(path.join(__dirname, 'file.xml'));
var xml = new XmlStream(stream);
xml.preserve('item', true);
xml.collect('subitem');
var arr = []
xml.on('endElement: item', function(item) {
arr.push(item)
});
xml.on('end', function(data) {
var highlandStream = _(data)
Land.emit('endStream', highlandStream)
});
Land.promise('endStream').then(function(stream) {
// now you can pipe your stream
})
Still, it is possible much more simpler and smarter solution if you use some of the alternative Node.js libraries for reading XML files.
I remend node-modules. and libraries.io/npm to improve the NPM search.