var expat = require('node-expat'); var fs = require('fs'); var parser = new expat.Parser('UTF-8'); // This object will hold the final result. var obj = {}; var currentParent = obj; var ancestors = []; function startElement(name, attrs) { if (! (name in currentParent)) { currentParent[name] = attrs; } else if (!(currentParent[name] instanceof Array)) { // Put the existing object in an array. var newArray = [currentParent[name]]; // Add the new object to the array. newArray.push(attrs); // Point to the new array. currentParent[name] = newArray; } else { // An array already exists, push the attributes on to it. currentParent[name].push(attrs); } // Store the current (old) parent. ancestors.push(currentParent); // We are now working with this object, so it becomes the current parent. if (currentParent[name] instanceof Array) { // If it is an array, get the last element of the array. currentParent = currentParent[name][currentParent[name].length - 1]; } else { // Otherwise, use the object itself. currentParent = currentParent[name]; } } function charData(data) { data = data.trim(); if (!data.length) { return; } currentParent['$t'] = data; } function endElement(name) { // This should check to make sure that the name we're ending // matches the name we started on. var ancestor = ancestors.pop(); if ((Object.keys(currentParent).length == 1) && ('$t' in currentParent)) { if (ancestor[name] instanceof Array) { //console.log("list-replacing $t in " + name); ancestor[name].push(ancestor[name].pop()['$t']); } else { //console.log("replacing $t in " + name); ancestor[name] = currentParent['$t']; } } else { //console.log("final " + name + ":"); //console.log(currentParent); } currentParent = ancestor; } parser.on('startElement', startElement); parser.on('text', charData); parser.on('endElement', endElement); module.exports.toJson = function(xml, _object) { _object = _object || false; if(parser.parse(xml)) { if(_object) { return obj; } return JSON.stringify(obj); } };