Node.js使用xml-stream进行XML转换

时间:2015-06-18 09:28:25

标签: javascript node.js stream

我正在使用xml-stream来读取大型XML文件。我想:

  1. 将收集的元素传输到流
  2. 可选地,使用一个或多个管道转换这些元素
  3. 将结果传递给http响应
  4. 以下xml-stream代码段收集了必需的元素:

    xml.on('endElement: item', function(item) {
      // pipe item to stream
    })
    

    如何为第1步和第2步构建流?

    P.S。 xml-stream只有console.log个例子

    更新1

    这是我到目前为止所写的内容:

    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会在每个write上调用,但是将liner流传输到http结果不会产生任何输出。

2 个答案:

答案 0 :(得分:4)

任务完成。下面的函数返回transform stream,可以通过管道传递到任何可写流。只有您想要在流的末尾添加一些数据时才需要liner._flush

P.S。一个方便的模块(此处未使用)https://github.com/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;
}

答案 1 :(得分:0)

也许您应该查看该库提供的示例。如果你已经这样做了,如果你已经指出了它会很好。 所以我使用Promised land来进行数据流,使用Highlandjs来创建一个来自数组的流,它只有一个元素 - item

最后,您有流,您可以根据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
    })

如果您使用一些备用Node.js库来读取XML文件,那么可能会有更简单,更智能的解决方案。

我建议使用node-modules.com和libraries.io/npm来改进NPM搜索。