Skip to content

Instantly share code, notes, and snippets.

@grimen
Last active April 13, 2017 18:49
Show Gist options
  • Save grimen/62c70bfb0878962abd11984960a99900 to your computer and use it in GitHub Desktop.
Save grimen/62c70bfb0878962abd11984960a99900 to your computer and use it in GitHub Desktop.
// =================================================================
// EXAMPLE: Product XML-to-JSON Stream Parser
// =================================================================
const fs = require('fs')
const sax = require('sax')
const stream = require('stream')
const JSONStream = require('JSONStream')
// ==============================================
// Initialize
// -----------------------------------------
console.log('BEGIN...')
// ==============================================
// Products (Object/JSON) Stream
// -----------------------------------------
const productsStream = new stream.Readable({objectMode: true})
productsStream.on('error', function (err) {
console.error('ERR', err)
})
// ==============================================
// XML Parser (SAX) Stream
// -----------------------------------------
const saxStream = sax.createStream(true, {})
let products = []
let product = undefined
let property = undefined
saxStream.on('error', function (err) {
console.error('ERR', err)
this._parser.error = null
this._parser.resume()
})
saxStream.on('opentag', function (tag) {
console.log('TAG:OPEN', tag.name)
if (tag.name === 'catalog') {
} else if (tag.name === 'product') {
product = {}
property = undefined
return
} else {
property = tag.name
}
})
saxStream.on('attribute', function (attribute) {
console.log('ATTRIBUTE', attribute)
})
saxStream.on('text', function (text) {
console.log('TEXT', text)
if (property) {
product[property] = product[property] || ''
product[property] += text
}
})
saxStream.on('closetag', function (name) {
console.log('TAG:CLOSE', name)
if (name === 'product') {
Object.keys(product).forEach((key) => {
product[key] = product[key].trim()
})
return productsStream.push(product)
}
})
saxStream.on('end', function () {
console.log('END')
})
// ==============================================
// Run
// -----------------------------------------
fs.createReadStream('/tmp/feed.xml')
.pipe(saxStream)
.pipe(process.stdout)
// .pipe(fs.createWriteStream('feed-copy.xml'))
productsStream
.pipe(JSONStream.stringify())
.pipe(process.stdout)
.pipe(fs.createWriteStream('products.json'))
// ==============================================
// Exit
// -----------------------------------------
process.stdout.on('drain', () => {
console.log('EXIT')
process.exit(1)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment